@moonbase.sh/storefront-api 3.5.1 → 3.6.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
@@ -110,6 +110,68 @@ another tenant's) arrives as the same `NotFoundError`, so that a signed-in
110
110
  customer cannot use it to enumerate a merchant's group IDs. Joining twice
111
111
  succeeds and changes nothing.
112
112
 
113
+ ### Captchas on sign-up
114
+
115
+ A merchant can ask customers to solve a captcha before they sign up. The vendor
116
+ says whether this store does:
117
+
118
+ ```ts
119
+ const vendor = await client.vendor.get()
120
+ const captcha = vendor.features?.captcha // { url } when it does, null or undefined when not
121
+ ```
122
+
123
+ `captcha.url` is a page on the store's own `<account-id>.moonbase.sh` that draws
124
+ the challenge. Embed it in an iframe with `action=signup`, and it hands you the
125
+ solution with `postMessage`:
126
+
127
+ ```ts
128
+ const src = new URL(captcha.url)
129
+ src.searchParams.set('action', 'signup') // optional: theme=light|dark|auto, size=normal|compact
130
+
131
+ const frame = document.createElement('iframe')
132
+ frame.src = src.href
133
+ frame.title = 'Captcha'
134
+ frame.style.cssText = 'border: none; color-scheme: normal; width: 300px; height: 65px'
135
+ form.append(frame)
136
+
137
+ let captchaToken: string | undefined
138
+ window.addEventListener('message', (event) => {
139
+ if (event.source !== frame.contentWindow || event.origin !== src.origin || event.data?.source !== 'moonbase-captcha')
140
+ return
141
+ if (event.data.event === 'resize')
142
+ Object.assign(frame.style, { width: `${event.data.width}px`, height: `${event.data.height}px` })
143
+ else if (event.data.event === 'token')
144
+ captchaToken = event.data.token
145
+ else // 'expired', or 'error' with a `code` ('load-failed' when the challenge could not load)
146
+ captchaToken = undefined
147
+ })
148
+ ```
149
+
150
+ Then pass the solution along, and reset the frame after every attempt, since a
151
+ solution is good for one:
152
+
153
+ ```ts
154
+ try {
155
+ await client.identity.signUp('Jane', 'jane@example.com', 'password', null, true, true, true, {
156
+ captchaToken,
157
+ })
158
+ }
159
+ catch (err) {
160
+ if (err instanceof CaptchaRequiredError)
161
+ showError(err.message) // the API's own copy, safe to show
162
+ throw err
163
+ }
164
+ finally {
165
+ captchaToken = undefined
166
+ frame.contentWindow?.postMessage({ source: 'moonbase-captcha', command: 'reset' }, src.origin)
167
+ }
168
+ ```
169
+
170
+ Without a solution, or with one that is expired or already used, the sign-up is
171
+ refused with `CaptchaRequiredError` (a `MoonbaseError`). A site with a
172
+ Content-Security-Policy has to allow the store's `https://<account-id>.moonbase.sh`
173
+ in `frame-src`.
174
+
113
175
  ## Inventory flow
114
176
 
115
177
  Most inventory endpoints require an authenticated user:
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  ActivationRequestStatus: () => ActivationRequestStatus,
26
26
  ActivationStatus: () => ActivationStatus,
27
27
  Architecture: () => Architecture,
28
+ CaptchaRequiredError: () => CaptchaRequiredError,
28
29
  CartUtils: () => CartUtils,
29
30
  ConnectableAccountProvider: () => ConnectableAccountProvider,
30
31
  ConsoleLogger: () => ConsoleLogger,
@@ -657,6 +658,12 @@ var MoonbaseError = class extends Error {
657
658
  }
658
659
  }
659
660
  };
661
+ var CaptchaRequiredError = class extends MoonbaseError {
662
+ constructor(detail, title) {
663
+ super(title != null ? title : "Captcha required", detail != null ? detail : "Please confirm you're not a robot.", 400);
664
+ this.name = "CaptchaRequiredError";
665
+ }
666
+ };
660
667
 
661
668
  // src/utils/problemDetails.ts
662
669
  var import_zod7 = require("zod");
@@ -699,6 +706,8 @@ async function handleResponseProblem(response, logger) {
699
706
  logger.debug("The response indicates a problem", problemDetails);
700
707
  if (problemDetails.errorType === "StoreClosed")
701
708
  throw new StoreClosedError(problemDetails.detail);
709
+ if (problemDetails.errorType === "CaptchaRequired")
710
+ throw new CaptchaRequiredError(problemDetails.detail, problemDetails.title);
702
711
  throw new MoonbaseError(
703
712
  problemDetails.title,
704
713
  problemDetails.detail,
@@ -835,7 +844,8 @@ var IdentityEndpoints = class {
835
844
  "Accept": "application/json",
836
845
  "Content-Type": "application/json",
837
846
  "x-mb-cors": "1",
838
- "x-mb-client": this.api.clientHeader
847
+ "x-mb-client": this.api.clientHeader,
848
+ ...(options == null ? void 0 : options.captchaToken) ? { "X-MB-CAPTCHA": options.captchaToken } : {}
839
849
  },
840
850
  body: JSON.stringify({
841
851
  name,
@@ -1098,7 +1108,7 @@ var ProductEndpoints = class {
1098
1108
  var import_zod14 = require("zod");
1099
1109
 
1100
1110
  // package.json
1101
- var version = "3.5.1";
1111
+ var version = "3.6.0";
1102
1112
 
1103
1113
  // src/utils/client.ts
1104
1114
  function buildClientHeader(sdk) {
@@ -1912,13 +1922,26 @@ var TokenStore = _TokenStore;
1912
1922
  // src/vendor/schemas.ts
1913
1923
  var schemas_exports9 = {};
1914
1924
  __export(schemas_exports9, {
1925
+ vendorCaptchaSchema: () => vendorCaptchaSchema,
1926
+ vendorFeaturesSchema: () => vendorFeaturesSchema,
1915
1927
  vendorSchema: () => vendorSchema
1916
1928
  });
1917
1929
  var import_zod15 = require("zod");
1930
+ var vendorCaptchaSchema = import_zod15.z.object({
1931
+ url: import_zod15.z.string()
1932
+ });
1933
+ var vendorFeaturesSchema = import_zod15.z.object({
1934
+ customerPortal: import_zod15.z.boolean().optional(),
1935
+ phoneNumber: import_zod15.z.boolean().optional(),
1936
+ marketingConsent: import_zod15.z.nativeEnum(MarketingConsentType).optional().catch(void 0),
1937
+ // Absent on backends from before captchas, which never ask for one.
1938
+ captcha: vendorCaptchaSchema.nullish()
1939
+ });
1918
1940
  var vendorSchema = import_zod15.z.object({
1919
1941
  id: import_zod15.z.string(),
1920
1942
  name: import_zod15.z.string(),
1921
- logoUrl: import_zod15.z.string().nullable()
1943
+ logoUrl: import_zod15.z.string().nullable(),
1944
+ features: vendorFeaturesSchema.optional()
1922
1945
  });
1923
1946
 
1924
1947
  // src/vendor/endpoints.ts
@@ -2614,6 +2637,7 @@ var MoonbaseClient = class {
2614
2637
  ActivationRequestStatus,
2615
2638
  ActivationStatus,
2616
2639
  Architecture,
2640
+ CaptchaRequiredError,
2617
2641
  CartUtils,
2618
2642
  ConnectableAccountProvider,
2619
2643
  ConsoleLogger,
package/dist/index.d.cts CHANGED
@@ -1677,6 +1677,15 @@ interface SignUpOptions {
1677
1677
  * ID left in a form can never fail a registration.
1678
1678
  */
1679
1679
  groupIds?: string[];
1680
+ /**
1681
+ * The customer's solution to the store's captcha, for stores that ask for one
1682
+ * (`vendor.features.captcha`). Sent in the `X-MB-CAPTCHA` header.
1683
+ *
1684
+ * Without it (or with one that does not check out) such a store refuses the
1685
+ * sign-up with a `CaptchaRequiredError`. Solutions are single-use and expire
1686
+ * after about two minutes, so reset the captcha after every attempt.
1687
+ */
1688
+ captchaToken?: string;
1680
1689
  }
1681
1690
 
1682
1691
  declare class IdentityEndpoints {
@@ -24989,26 +24998,110 @@ declare class StorefrontEndpoints {
24989
24998
  }>;
24990
24999
  }
24991
25000
 
25001
+ /**
25002
+ * The captcha a store asks customers to solve before signing up and checking out. `url` is a
25003
+ * page on the store's own `<account-id>.moonbase.sh` that draws the challenge: embed it in an
25004
+ * iframe, and it hands the solution to its parent with `postMessage`.
25005
+ */
25006
+ declare const vendorCaptchaSchema: z.ZodObject<{
25007
+ url: z.ZodString;
25008
+ }, "strip", z.ZodTypeAny, {
25009
+ url: string;
25010
+ }, {
25011
+ url: string;
25012
+ }>;
25013
+ declare const vendorFeaturesSchema: z.ZodObject<{
25014
+ customerPortal: z.ZodOptional<z.ZodBoolean>;
25015
+ phoneNumber: z.ZodOptional<z.ZodBoolean>;
25016
+ marketingConsent: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<typeof MarketingConsentType>>>;
25017
+ captcha: z.ZodOptional<z.ZodNullable<z.ZodObject<{
25018
+ url: z.ZodString;
25019
+ }, "strip", z.ZodTypeAny, {
25020
+ url: string;
25021
+ }, {
25022
+ url: string;
25023
+ }>>>;
25024
+ }, "strip", z.ZodTypeAny, {
25025
+ customerPortal?: boolean | undefined;
25026
+ phoneNumber?: boolean | undefined;
25027
+ marketingConsent?: MarketingConsentType | undefined;
25028
+ captcha?: {
25029
+ url: string;
25030
+ } | null | undefined;
25031
+ }, {
25032
+ customerPortal?: boolean | undefined;
25033
+ phoneNumber?: boolean | undefined;
25034
+ marketingConsent?: unknown;
25035
+ captcha?: {
25036
+ url: string;
25037
+ } | null | undefined;
25038
+ }>;
24992
25039
  declare const vendorSchema: z.ZodObject<{
24993
25040
  id: z.ZodString;
24994
25041
  name: z.ZodString;
24995
25042
  logoUrl: z.ZodNullable<z.ZodString>;
25043
+ features: z.ZodOptional<z.ZodObject<{
25044
+ customerPortal: z.ZodOptional<z.ZodBoolean>;
25045
+ phoneNumber: z.ZodOptional<z.ZodBoolean>;
25046
+ marketingConsent: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<typeof MarketingConsentType>>>;
25047
+ captcha: z.ZodOptional<z.ZodNullable<z.ZodObject<{
25048
+ url: z.ZodString;
25049
+ }, "strip", z.ZodTypeAny, {
25050
+ url: string;
25051
+ }, {
25052
+ url: string;
25053
+ }>>>;
25054
+ }, "strip", z.ZodTypeAny, {
25055
+ customerPortal?: boolean | undefined;
25056
+ phoneNumber?: boolean | undefined;
25057
+ marketingConsent?: MarketingConsentType | undefined;
25058
+ captcha?: {
25059
+ url: string;
25060
+ } | null | undefined;
25061
+ }, {
25062
+ customerPortal?: boolean | undefined;
25063
+ phoneNumber?: boolean | undefined;
25064
+ marketingConsent?: unknown;
25065
+ captcha?: {
25066
+ url: string;
25067
+ } | null | undefined;
25068
+ }>>;
24996
25069
  }, "strip", z.ZodTypeAny, {
24997
25070
  id: string;
24998
25071
  name: string;
24999
25072
  logoUrl: string | null;
25073
+ features?: {
25074
+ customerPortal?: boolean | undefined;
25075
+ phoneNumber?: boolean | undefined;
25076
+ marketingConsent?: MarketingConsentType | undefined;
25077
+ captcha?: {
25078
+ url: string;
25079
+ } | null | undefined;
25080
+ } | undefined;
25000
25081
  }, {
25001
25082
  id: string;
25002
25083
  name: string;
25003
25084
  logoUrl: string | null;
25085
+ features?: {
25086
+ customerPortal?: boolean | undefined;
25087
+ phoneNumber?: boolean | undefined;
25088
+ marketingConsent?: unknown;
25089
+ captcha?: {
25090
+ url: string;
25091
+ } | null | undefined;
25092
+ } | undefined;
25004
25093
  }>;
25005
25094
 
25095
+ declare const schemas$4_vendorCaptchaSchema: typeof vendorCaptchaSchema;
25096
+ declare const schemas$4_vendorFeaturesSchema: typeof vendorFeaturesSchema;
25006
25097
  declare const schemas$4_vendorSchema: typeof vendorSchema;
25007
25098
  declare namespace schemas$4 {
25008
- export { schemas$4_vendorSchema as vendorSchema };
25099
+ export { schemas$4_vendorCaptchaSchema as vendorCaptchaSchema, schemas$4_vendorFeaturesSchema as vendorFeaturesSchema, schemas$4_vendorSchema as vendorSchema };
25009
25100
  }
25010
25101
 
25011
25102
  type Vendor = z.infer<typeof vendorSchema>;
25103
+ type VendorFeatures = z.infer<typeof vendorFeaturesSchema>;
25104
+ type VendorCaptcha = z.infer<typeof vendorCaptchaSchema>;
25012
25105
 
25013
25106
  declare class VendorEndpoints {
25014
25107
  private api;
@@ -47026,6 +47119,17 @@ declare class MoonbaseError extends Error {
47026
47119
  readonly errors?: Record<string, string> | undefined;
47027
47120
  constructor(title: string, detail: string | undefined, status?: number | undefined, errors?: Record<string, string> | undefined);
47028
47121
  }
47122
+ /**
47123
+ * The store asks customers to solve a captcha (see `Vendor.features.captcha`), and the request
47124
+ * carried none, or one that did not check out: unsolved, expired, already used, or solved on a
47125
+ * site that is not one of the store's. `message` is the API's own copy for the customer, safe to
47126
+ * show as is. Solutions are single-use, so reset the captcha and let them try again.
47127
+ *
47128
+ * A `MoonbaseError` like any other refusal, so code that already handles those keeps working.
47129
+ */
47130
+ declare class CaptchaRequiredError extends MoonbaseError {
47131
+ constructor(detail?: string, title?: string);
47132
+ }
47029
47133
 
47030
47134
  /**
47031
47135
  * Cleans up merchant-authored group IDs before they go on the wire.
@@ -47206,4 +47310,4 @@ declare class MoonbaseClient {
47206
47310
  orders: OrderEndpoints;
47207
47311
  }
47208
47312
 
47209
- export { type Activation, ActivationMethod, type ActivationRequest, ActivationRequestFulfillmentType, ActivationRequestStatus, ActivationStatus, type Address, Architecture, type BundleLineItem, type CartCatalog, type CartOrder, type CartTotal, type CartTotalCondition, CartUtils, type CommunicationPreferences, type CommunicationPreferencesInput, type CommunicationPreferencesView, type CompletedOrder, ConnectableAccountProvider, type ConnectedAccount, ConsoleLogger, CycleLength, type Discount, DiscountUtils, type Download, type DownloadManifest, type ILogger, type IRecurrence, type IStore, type ITokenStore, type Identity, type ImageFit, type ImageFormat, type ImageTransform, ImageUtils, InMemoryStore, type License, LicenseStatus, type LineItem, type LineItemTotal, LocalStorageStore, LogLevel, MarketingConsentType, type MilestoneProgress, type Money, type MoneyCollection, MoneyCollectionUtils, MoonbaseApi, MoonbaseClient, type MoonbaseConfiguration, MoonbaseError, NotAuthenticatedError, NotAuthorizedError, NotFoundError, type OfferCondition, type OfferConditionContext, type OfferProgress, type OfferScope, OfferUtils, type OpenOrder, type Order, OrderStatus, type OrderTotal, type OwnedProduct, type Page, Platform, type PricingTier, type PricingVariation, type ProblemDetails, type ProductLineItem, type PromotionDisplay, type Quantifiable, type RawPropertyArray, type RawPropertyObject, type RawPropertyValue, type SignUpOptions, type SignUpResult, type SingleOrMultiple, StoreClosedError, type Storefront, type StorefrontBundle, type StorefrontOffer, type StorefrontOfferTarget, type StorefrontProduct, type StorefrontPromotion, type StorefrontPromotionCta, type StorefrontPromotionTarget, type SubscribeInput, type SubscribeResponse, type Subscription, type SubscriptionCancellationFeedback, SubscriptionCancellationReason, SubscriptionStatus, type TaxEstimate, TokenStore, type UrchinTrackingModule, type User, type UserAccountConfirmed, type UserAccountConfirmedStatus, type Vendor, type Voucher, imageWidths, isLocalStorageAvailable, isPromotionDisplay, isTransformableImageUrl, maxImageDimension, normalizeGroupIds, objectToQuery, parseOffSiteReferrer, problemDetailsSchema, promotionDisplays, resolveUtm, schemas, utmToObject };
47313
+ export { type Activation, ActivationMethod, type ActivationRequest, ActivationRequestFulfillmentType, ActivationRequestStatus, ActivationStatus, type Address, Architecture, type BundleLineItem, CaptchaRequiredError, type CartCatalog, type CartOrder, type CartTotal, type CartTotalCondition, CartUtils, type CommunicationPreferences, type CommunicationPreferencesInput, type CommunicationPreferencesView, type CompletedOrder, ConnectableAccountProvider, type ConnectedAccount, ConsoleLogger, CycleLength, type Discount, DiscountUtils, type Download, type DownloadManifest, type ILogger, type IRecurrence, type IStore, type ITokenStore, type Identity, type ImageFit, type ImageFormat, type ImageTransform, ImageUtils, InMemoryStore, type License, LicenseStatus, type LineItem, type LineItemTotal, LocalStorageStore, LogLevel, MarketingConsentType, type MilestoneProgress, type Money, type MoneyCollection, MoneyCollectionUtils, MoonbaseApi, MoonbaseClient, type MoonbaseConfiguration, MoonbaseError, NotAuthenticatedError, NotAuthorizedError, NotFoundError, type OfferCondition, type OfferConditionContext, type OfferProgress, type OfferScope, OfferUtils, type OpenOrder, type Order, OrderStatus, type OrderTotal, type OwnedProduct, type Page, Platform, type PricingTier, type PricingVariation, type ProblemDetails, type ProductLineItem, type PromotionDisplay, type Quantifiable, type RawPropertyArray, type RawPropertyObject, type RawPropertyValue, type SignUpOptions, type SignUpResult, type SingleOrMultiple, StoreClosedError, type Storefront, type StorefrontBundle, type StorefrontOffer, type StorefrontOfferTarget, type StorefrontProduct, type StorefrontPromotion, type StorefrontPromotionCta, type StorefrontPromotionTarget, type SubscribeInput, type SubscribeResponse, type Subscription, type SubscriptionCancellationFeedback, SubscriptionCancellationReason, SubscriptionStatus, type TaxEstimate, TokenStore, type UrchinTrackingModule, type User, type UserAccountConfirmed, type UserAccountConfirmedStatus, type Vendor, type VendorCaptcha, type VendorFeatures, type Voucher, imageWidths, isLocalStorageAvailable, isPromotionDisplay, isTransformableImageUrl, maxImageDimension, normalizeGroupIds, objectToQuery, parseOffSiteReferrer, problemDetailsSchema, promotionDisplays, resolveUtm, schemas, utmToObject };
package/dist/index.d.ts CHANGED
@@ -1677,6 +1677,15 @@ interface SignUpOptions {
1677
1677
  * ID left in a form can never fail a registration.
1678
1678
  */
1679
1679
  groupIds?: string[];
1680
+ /**
1681
+ * The customer's solution to the store's captcha, for stores that ask for one
1682
+ * (`vendor.features.captcha`). Sent in the `X-MB-CAPTCHA` header.
1683
+ *
1684
+ * Without it (or with one that does not check out) such a store refuses the
1685
+ * sign-up with a `CaptchaRequiredError`. Solutions are single-use and expire
1686
+ * after about two minutes, so reset the captcha after every attempt.
1687
+ */
1688
+ captchaToken?: string;
1680
1689
  }
1681
1690
 
1682
1691
  declare class IdentityEndpoints {
@@ -24989,26 +24998,110 @@ declare class StorefrontEndpoints {
24989
24998
  }>;
24990
24999
  }
24991
25000
 
25001
+ /**
25002
+ * The captcha a store asks customers to solve before signing up and checking out. `url` is a
25003
+ * page on the store's own `<account-id>.moonbase.sh` that draws the challenge: embed it in an
25004
+ * iframe, and it hands the solution to its parent with `postMessage`.
25005
+ */
25006
+ declare const vendorCaptchaSchema: z.ZodObject<{
25007
+ url: z.ZodString;
25008
+ }, "strip", z.ZodTypeAny, {
25009
+ url: string;
25010
+ }, {
25011
+ url: string;
25012
+ }>;
25013
+ declare const vendorFeaturesSchema: z.ZodObject<{
25014
+ customerPortal: z.ZodOptional<z.ZodBoolean>;
25015
+ phoneNumber: z.ZodOptional<z.ZodBoolean>;
25016
+ marketingConsent: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<typeof MarketingConsentType>>>;
25017
+ captcha: z.ZodOptional<z.ZodNullable<z.ZodObject<{
25018
+ url: z.ZodString;
25019
+ }, "strip", z.ZodTypeAny, {
25020
+ url: string;
25021
+ }, {
25022
+ url: string;
25023
+ }>>>;
25024
+ }, "strip", z.ZodTypeAny, {
25025
+ customerPortal?: boolean | undefined;
25026
+ phoneNumber?: boolean | undefined;
25027
+ marketingConsent?: MarketingConsentType | undefined;
25028
+ captcha?: {
25029
+ url: string;
25030
+ } | null | undefined;
25031
+ }, {
25032
+ customerPortal?: boolean | undefined;
25033
+ phoneNumber?: boolean | undefined;
25034
+ marketingConsent?: unknown;
25035
+ captcha?: {
25036
+ url: string;
25037
+ } | null | undefined;
25038
+ }>;
24992
25039
  declare const vendorSchema: z.ZodObject<{
24993
25040
  id: z.ZodString;
24994
25041
  name: z.ZodString;
24995
25042
  logoUrl: z.ZodNullable<z.ZodString>;
25043
+ features: z.ZodOptional<z.ZodObject<{
25044
+ customerPortal: z.ZodOptional<z.ZodBoolean>;
25045
+ phoneNumber: z.ZodOptional<z.ZodBoolean>;
25046
+ marketingConsent: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<typeof MarketingConsentType>>>;
25047
+ captcha: z.ZodOptional<z.ZodNullable<z.ZodObject<{
25048
+ url: z.ZodString;
25049
+ }, "strip", z.ZodTypeAny, {
25050
+ url: string;
25051
+ }, {
25052
+ url: string;
25053
+ }>>>;
25054
+ }, "strip", z.ZodTypeAny, {
25055
+ customerPortal?: boolean | undefined;
25056
+ phoneNumber?: boolean | undefined;
25057
+ marketingConsent?: MarketingConsentType | undefined;
25058
+ captcha?: {
25059
+ url: string;
25060
+ } | null | undefined;
25061
+ }, {
25062
+ customerPortal?: boolean | undefined;
25063
+ phoneNumber?: boolean | undefined;
25064
+ marketingConsent?: unknown;
25065
+ captcha?: {
25066
+ url: string;
25067
+ } | null | undefined;
25068
+ }>>;
24996
25069
  }, "strip", z.ZodTypeAny, {
24997
25070
  id: string;
24998
25071
  name: string;
24999
25072
  logoUrl: string | null;
25073
+ features?: {
25074
+ customerPortal?: boolean | undefined;
25075
+ phoneNumber?: boolean | undefined;
25076
+ marketingConsent?: MarketingConsentType | undefined;
25077
+ captcha?: {
25078
+ url: string;
25079
+ } | null | undefined;
25080
+ } | undefined;
25000
25081
  }, {
25001
25082
  id: string;
25002
25083
  name: string;
25003
25084
  logoUrl: string | null;
25085
+ features?: {
25086
+ customerPortal?: boolean | undefined;
25087
+ phoneNumber?: boolean | undefined;
25088
+ marketingConsent?: unknown;
25089
+ captcha?: {
25090
+ url: string;
25091
+ } | null | undefined;
25092
+ } | undefined;
25004
25093
  }>;
25005
25094
 
25095
+ declare const schemas$4_vendorCaptchaSchema: typeof vendorCaptchaSchema;
25096
+ declare const schemas$4_vendorFeaturesSchema: typeof vendorFeaturesSchema;
25006
25097
  declare const schemas$4_vendorSchema: typeof vendorSchema;
25007
25098
  declare namespace schemas$4 {
25008
- export { schemas$4_vendorSchema as vendorSchema };
25099
+ export { schemas$4_vendorCaptchaSchema as vendorCaptchaSchema, schemas$4_vendorFeaturesSchema as vendorFeaturesSchema, schemas$4_vendorSchema as vendorSchema };
25009
25100
  }
25010
25101
 
25011
25102
  type Vendor = z.infer<typeof vendorSchema>;
25103
+ type VendorFeatures = z.infer<typeof vendorFeaturesSchema>;
25104
+ type VendorCaptcha = z.infer<typeof vendorCaptchaSchema>;
25012
25105
 
25013
25106
  declare class VendorEndpoints {
25014
25107
  private api;
@@ -47026,6 +47119,17 @@ declare class MoonbaseError extends Error {
47026
47119
  readonly errors?: Record<string, string> | undefined;
47027
47120
  constructor(title: string, detail: string | undefined, status?: number | undefined, errors?: Record<string, string> | undefined);
47028
47121
  }
47122
+ /**
47123
+ * The store asks customers to solve a captcha (see `Vendor.features.captcha`), and the request
47124
+ * carried none, or one that did not check out: unsolved, expired, already used, or solved on a
47125
+ * site that is not one of the store's. `message` is the API's own copy for the customer, safe to
47126
+ * show as is. Solutions are single-use, so reset the captcha and let them try again.
47127
+ *
47128
+ * A `MoonbaseError` like any other refusal, so code that already handles those keeps working.
47129
+ */
47130
+ declare class CaptchaRequiredError extends MoonbaseError {
47131
+ constructor(detail?: string, title?: string);
47132
+ }
47029
47133
 
47030
47134
  /**
47031
47135
  * Cleans up merchant-authored group IDs before they go on the wire.
@@ -47206,4 +47310,4 @@ declare class MoonbaseClient {
47206
47310
  orders: OrderEndpoints;
47207
47311
  }
47208
47312
 
47209
- export { type Activation, ActivationMethod, type ActivationRequest, ActivationRequestFulfillmentType, ActivationRequestStatus, ActivationStatus, type Address, Architecture, type BundleLineItem, type CartCatalog, type CartOrder, type CartTotal, type CartTotalCondition, CartUtils, type CommunicationPreferences, type CommunicationPreferencesInput, type CommunicationPreferencesView, type CompletedOrder, ConnectableAccountProvider, type ConnectedAccount, ConsoleLogger, CycleLength, type Discount, DiscountUtils, type Download, type DownloadManifest, type ILogger, type IRecurrence, type IStore, type ITokenStore, type Identity, type ImageFit, type ImageFormat, type ImageTransform, ImageUtils, InMemoryStore, type License, LicenseStatus, type LineItem, type LineItemTotal, LocalStorageStore, LogLevel, MarketingConsentType, type MilestoneProgress, type Money, type MoneyCollection, MoneyCollectionUtils, MoonbaseApi, MoonbaseClient, type MoonbaseConfiguration, MoonbaseError, NotAuthenticatedError, NotAuthorizedError, NotFoundError, type OfferCondition, type OfferConditionContext, type OfferProgress, type OfferScope, OfferUtils, type OpenOrder, type Order, OrderStatus, type OrderTotal, type OwnedProduct, type Page, Platform, type PricingTier, type PricingVariation, type ProblemDetails, type ProductLineItem, type PromotionDisplay, type Quantifiable, type RawPropertyArray, type RawPropertyObject, type RawPropertyValue, type SignUpOptions, type SignUpResult, type SingleOrMultiple, StoreClosedError, type Storefront, type StorefrontBundle, type StorefrontOffer, type StorefrontOfferTarget, type StorefrontProduct, type StorefrontPromotion, type StorefrontPromotionCta, type StorefrontPromotionTarget, type SubscribeInput, type SubscribeResponse, type Subscription, type SubscriptionCancellationFeedback, SubscriptionCancellationReason, SubscriptionStatus, type TaxEstimate, TokenStore, type UrchinTrackingModule, type User, type UserAccountConfirmed, type UserAccountConfirmedStatus, type Vendor, type Voucher, imageWidths, isLocalStorageAvailable, isPromotionDisplay, isTransformableImageUrl, maxImageDimension, normalizeGroupIds, objectToQuery, parseOffSiteReferrer, problemDetailsSchema, promotionDisplays, resolveUtm, schemas, utmToObject };
47313
+ export { type Activation, ActivationMethod, type ActivationRequest, ActivationRequestFulfillmentType, ActivationRequestStatus, ActivationStatus, type Address, Architecture, type BundleLineItem, CaptchaRequiredError, type CartCatalog, type CartOrder, type CartTotal, type CartTotalCondition, CartUtils, type CommunicationPreferences, type CommunicationPreferencesInput, type CommunicationPreferencesView, type CompletedOrder, ConnectableAccountProvider, type ConnectedAccount, ConsoleLogger, CycleLength, type Discount, DiscountUtils, type Download, type DownloadManifest, type ILogger, type IRecurrence, type IStore, type ITokenStore, type Identity, type ImageFit, type ImageFormat, type ImageTransform, ImageUtils, InMemoryStore, type License, LicenseStatus, type LineItem, type LineItemTotal, LocalStorageStore, LogLevel, MarketingConsentType, type MilestoneProgress, type Money, type MoneyCollection, MoneyCollectionUtils, MoonbaseApi, MoonbaseClient, type MoonbaseConfiguration, MoonbaseError, NotAuthenticatedError, NotAuthorizedError, NotFoundError, type OfferCondition, type OfferConditionContext, type OfferProgress, type OfferScope, OfferUtils, type OpenOrder, type Order, OrderStatus, type OrderTotal, type OwnedProduct, type Page, Platform, type PricingTier, type PricingVariation, type ProblemDetails, type ProductLineItem, type PromotionDisplay, type Quantifiable, type RawPropertyArray, type RawPropertyObject, type RawPropertyValue, type SignUpOptions, type SignUpResult, type SingleOrMultiple, StoreClosedError, type Storefront, type StorefrontBundle, type StorefrontOffer, type StorefrontOfferTarget, type StorefrontProduct, type StorefrontPromotion, type StorefrontPromotionCta, type StorefrontPromotionTarget, type SubscribeInput, type SubscribeResponse, type Subscription, type SubscriptionCancellationFeedback, SubscriptionCancellationReason, SubscriptionStatus, type TaxEstimate, TokenStore, type UrchinTrackingModule, type User, type UserAccountConfirmed, type UserAccountConfirmedStatus, type Vendor, type VendorCaptcha, type VendorFeatures, type Voucher, imageWidths, isLocalStorageAvailable, isPromotionDisplay, isTransformableImageUrl, maxImageDimension, normalizeGroupIds, objectToQuery, parseOffSiteReferrer, problemDetailsSchema, promotionDisplays, resolveUtm, schemas, utmToObject };
package/dist/index.js CHANGED
@@ -595,6 +595,12 @@ var MoonbaseError = class extends Error {
595
595
  }
596
596
  }
597
597
  };
598
+ var CaptchaRequiredError = class extends MoonbaseError {
599
+ constructor(detail, title) {
600
+ super(title != null ? title : "Captcha required", detail != null ? detail : "Please confirm you're not a robot.", 400);
601
+ this.name = "CaptchaRequiredError";
602
+ }
603
+ };
598
604
 
599
605
  // src/utils/problemDetails.ts
600
606
  import { z as z7 } from "zod";
@@ -637,6 +643,8 @@ async function handleResponseProblem(response, logger) {
637
643
  logger.debug("The response indicates a problem", problemDetails);
638
644
  if (problemDetails.errorType === "StoreClosed")
639
645
  throw new StoreClosedError(problemDetails.detail);
646
+ if (problemDetails.errorType === "CaptchaRequired")
647
+ throw new CaptchaRequiredError(problemDetails.detail, problemDetails.title);
640
648
  throw new MoonbaseError(
641
649
  problemDetails.title,
642
650
  problemDetails.detail,
@@ -773,7 +781,8 @@ var IdentityEndpoints = class {
773
781
  "Accept": "application/json",
774
782
  "Content-Type": "application/json",
775
783
  "x-mb-cors": "1",
776
- "x-mb-client": this.api.clientHeader
784
+ "x-mb-client": this.api.clientHeader,
785
+ ...(options == null ? void 0 : options.captchaToken) ? { "X-MB-CAPTCHA": options.captchaToken } : {}
777
786
  },
778
787
  body: JSON.stringify({
779
788
  name,
@@ -1036,7 +1045,7 @@ var ProductEndpoints = class {
1036
1045
  import { z as z14 } from "zod";
1037
1046
 
1038
1047
  // package.json
1039
- var version = "3.5.1";
1048
+ var version = "3.6.0";
1040
1049
 
1041
1050
  // src/utils/client.ts
1042
1051
  function buildClientHeader(sdk) {
@@ -1850,13 +1859,26 @@ var TokenStore = _TokenStore;
1850
1859
  // src/vendor/schemas.ts
1851
1860
  var schemas_exports9 = {};
1852
1861
  __export(schemas_exports9, {
1862
+ vendorCaptchaSchema: () => vendorCaptchaSchema,
1863
+ vendorFeaturesSchema: () => vendorFeaturesSchema,
1853
1864
  vendorSchema: () => vendorSchema
1854
1865
  });
1855
1866
  import { z as z15 } from "zod";
1867
+ var vendorCaptchaSchema = z15.object({
1868
+ url: z15.string()
1869
+ });
1870
+ var vendorFeaturesSchema = z15.object({
1871
+ customerPortal: z15.boolean().optional(),
1872
+ phoneNumber: z15.boolean().optional(),
1873
+ marketingConsent: z15.nativeEnum(MarketingConsentType).optional().catch(void 0),
1874
+ // Absent on backends from before captchas, which never ask for one.
1875
+ captcha: vendorCaptchaSchema.nullish()
1876
+ });
1856
1877
  var vendorSchema = z15.object({
1857
1878
  id: z15.string(),
1858
1879
  name: z15.string(),
1859
- logoUrl: z15.string().nullable()
1880
+ logoUrl: z15.string().nullable(),
1881
+ features: vendorFeaturesSchema.optional()
1860
1882
  });
1861
1883
 
1862
1884
  // src/vendor/endpoints.ts
@@ -2551,6 +2573,7 @@ export {
2551
2573
  ActivationRequestStatus,
2552
2574
  ActivationStatus,
2553
2575
  Architecture,
2576
+ CaptchaRequiredError,
2554
2577
  CartUtils,
2555
2578
  ConnectableAccountProvider,
2556
2579
  ConsoleLogger,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@moonbase.sh/storefront-api",
3
3
  "type": "module",
4
- "version": "3.5.1",
4
+ "version": "3.6.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",