@misiki/gocommerce-connector 0.16.0 → 0.20.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
@@ -142,6 +142,7 @@ down stays best-effort: the storefront renders from its static record.
142
142
  | PIN code autofill | `/api/postcodes/IN/{pin}` — `addressService.lookupPostcode({ country, postcode })`: city and state, or null when the engine has no directory or the PIN is unknown (D134) |
143
143
  | wishlist | `/x/wishlist` |
144
144
  | reviews | `/x/reviews` |
145
+ | Google reviews | `/x/google-reviews/place` — `googleReviewService.place()`: the store's Google rating, rating count and up to five Google reviews with their authors' names, photos and profile links, read live on every call because Google's terms forbid keeping them (call it when the section is in view; each call is billed to the store's Google key). Null while ext/google-reviews or its `show_place` switch is off, when the place has no ratings, when the day's lookups are spent (429) or Google refuses (502). `/x/google-reviews/survey/{number}` — `googleReviewService.survey(number)`: Google Customer Reviews' opt-in fields, built by the engine from an order placed in this browser, read with its access token; null for any other order or while `customer_reviews` is off |
145
146
  | content pages (`/p/…`, legal pages) | `/x/cms/pages` |
146
147
  | FAQ | `/x/faq` |
147
148
  | composed home page | `/x/layouts/home` (`?preview=` for a draft) — `layoutService.getHomeLayout()`, null when the store has none; carries `themeSettings` and each collection list's `collections` |
@@ -154,7 +155,7 @@ down stays best-effort: the storefront renders from its static record.
154
155
  | newsletter box | `/x/newsletter/subscribe` |
155
156
  | contact form, product enquiries | `/x/contact/messages`, with the form's hidden `website` honeypot passed on so the engine drops what a bot filled in |
156
157
  | search words, type-ahead (plugin on) | `/x/meilisearch/search`, falling back to the engine's own search when it is off or down |
157
- | store record | the storefront's own config, with the engine's currency, menus and module switches over it; the store's own logo, dark logo and icon (`logo_url`, `logo_dark_url`, `icon_url` from `/api/store`, D148) replace `logo`, `logoDark` and `favicon` when it has them; for the contact page (D156), the address once the store shows it (as `address: { street, city, state, pincode, country }`), `mapLocation` and `openingHours` when set, `businessCountry` (the store's ISO country, for the phone's country code), and the `whatsapp-chat` plugin's number as `plugins.whatsappChatButton` |
158
+ | store record | the storefront's own config, with the engine's currency, menus and module switches over it; the store's own logo, dark logo and icon (`logo_url`, `logo_dark_url`, `icon_url` from `/api/store`, D148) replace `logo`, `logoDark` and `favicon` when it has them; for the contact page (D156), the address once the store shows it (as `address: { street, city, state, pincode, country }`), `mapLocation` and `openingHours` when set, `businessCountry` (the store's ISO country, for the phone's country code), the `whatsapp-chat` plugin's number as `plugins.whatsappChatButton`, and Google Customer Reviews (ext/google-reviews) as `plugins.googleReviewsOptIn` (`active` while the survey is on) and `plugins.googleStoreWidget` (`{ active, position: 'RIGHT_BOTTOM' \| 'LEFT_BOTTOM' }`, off without the survey) |
158
159
  | resized product pictures | `/images/{store}/cdn-cgi/image/width=…/…` — the store record's `plugins.imageCdn` is turned on with provider `cloudflare` and the engine's `images_path` (from `/api/store`, D139) after `PUBLIC_GOCOMMERCE_API_URL`, so the storefront's srcset asks the engine for each width; an engine without it leaves the static record's setting |
159
160
 
160
161
  Blogs, banners, reels, chat, warranties, deals and uploads have no engine
@@ -418,6 +418,36 @@ type Plugin = {
418
418
  title: string;
419
419
  settings: Record<string, unknown>;
420
420
  };
421
+ /** `GET /x/google-reviews/place` (ext/google-reviews): Google's answer just now, never stored. */
422
+ type GooglePlace = {
423
+ rating: number;
424
+ user_rating_count: number;
425
+ google_maps_uri: string;
426
+ reviews: {
427
+ author: {
428
+ name: string;
429
+ uri?: string;
430
+ photo_uri?: string;
431
+ };
432
+ rating: number;
433
+ text?: string;
434
+ language?: string;
435
+ relative_time?: string;
436
+ publish_time?: string;
437
+ visit_date?: string;
438
+ google_maps_uri?: string;
439
+ flag_uri?: string;
440
+ }[];
441
+ };
442
+ /** `GET /x/google-reviews/survey/{number}`: Google Customer Reviews' opt-in fields, from the order. */
443
+ type GoogleSurvey = {
444
+ merchant_id: number;
445
+ order_id: string;
446
+ email: string;
447
+ delivery_country: string;
448
+ estimated_delivery_date: string;
449
+ opt_in_style?: string;
450
+ };
421
451
  /** `GET /api/store`: what anyone may read about the shop. */
422
452
  type StoreProfile = {
423
453
  name: string;
@@ -685,10 +715,14 @@ type CartExtras = {
685
715
  currency: string;
686
716
  } | null;
687
717
  discount?: AppliedDiscount | null;
688
- /** The Idempotency-Key of the last checkout attempt, and the body it was sent with. */
718
+ /**
719
+ * The Idempotency-Key of the last checkout attempt, the body it was sent with, and where
720
+ * Meta's pixel ran then, which a retry sends again unchanged.
721
+ */
689
722
  attempt?: {
690
723
  key: string;
691
724
  body: string;
725
+ meta?: Record<string, string>;
692
726
  } | null;
693
727
  };
694
728
 
@@ -6150,6 +6184,60 @@ declare class ReviewService extends BaseService {
6150
6184
  }
6151
6185
  declare const reviewService: ReviewService;
6152
6186
 
6187
+ /** A Google review with what Google's attribution policy asks a storefront to show. */
6188
+ type GoogleReview = {
6189
+ author: string;
6190
+ /** The author's Google profile and photo; https or empty. */
6191
+ authorUrl: string;
6192
+ authorPhoto: string;
6193
+ rating: number;
6194
+ /** The reviewer's own words, in their language. Empty for a rating with no words. */
6195
+ text: string;
6196
+ language: string;
6197
+ /** Google's own words for when, such as "a month ago". */
6198
+ when: string;
6199
+ /** YYYY-MM, when Google has one. */
6200
+ visited: string;
6201
+ /** The review on Google Maps, and where to report it to Google. */
6202
+ url: string;
6203
+ reportUrl: string;
6204
+ };
6205
+ type GoogleReviews = {
6206
+ /** Google's own rating and count, never worked out from `reviews`. */
6207
+ rating: number;
6208
+ count: number;
6209
+ /** Every review, on Google Maps: `reviews` are at most five of them. */
6210
+ mapsUrl: string;
6211
+ reviews: GoogleReview[];
6212
+ };
6213
+ /**
6214
+ * The store's Google reviews and Google Customer Reviews (ext/google-reviews).
6215
+ *
6216
+ * Both calls answer null when there is nothing to show — the plugin or its
6217
+ * switch off, Google refusing, the day's lookups spent — because each is an
6218
+ * extra on a page that must render without it.
6219
+ */
6220
+ declare class GoogleReviewService extends BaseService {
6221
+ private readonly facts;
6222
+ /**
6223
+ * Google's rating and its most relevant reviews, read live. Google's terms
6224
+ * forbid keeping them, so nothing here caches them either, and every call
6225
+ * is one the store pays Google for: call it when the section is in view.
6226
+ */
6227
+ place(): Promise<GoogleReviews | null>;
6228
+ /**
6229
+ * What Google Customer Reviews' opt-in is rendered with, for an order placed
6230
+ * in this browser: its access token is kept here, and nowhere else can ask.
6231
+ * Every field is the order's own; the keys are Google's, to pass unchanged
6232
+ * to `gapi.surveyoptin.render`.
6233
+ */
6234
+ survey(orderNumber: string): Promise<GoogleSurvey | null>;
6235
+ private switchOn;
6236
+ /** Off, used up for the day, or refused by Google: nothing to show. Anything else still throws. */
6237
+ private orNull;
6238
+ }
6239
+ declare const googleReviewService: GoogleReviewService;
6240
+
6153
6241
  type StorefrontMenu = {
6154
6242
  menuId: string;
6155
6243
  name: string;
@@ -7609,4 +7697,4 @@ declare class B2bService extends BaseService {
7609
7697
  }
7610
7698
  declare const b2bService: B2bService;
7611
7699
 
7612
- export { HomeService as $, type AddOn as A, type B2bPlaced as B, type Cart as C, type CompanyOrder as D, ContactService as E, CountryService as F, CouponService as G, type Credentials as H, type Credit as I, CurrencyService as J, type Customer as K, DealService as L, DemoRequestService as M, type EngineRequest as N, EnquiryService as O, type Envelope as P, type FacetValue as Q, type Faq as R, FaqService as S, FeedbackService as T, type FooterSettings as U, type FreeShipping as V, type Fulfillment as W, GalleryService as X, type HeaderSettings as Y, type HomeLayout as Z, type HomeLayoutSection as _, type Address as a, type Variant as a$, type IdentityAddress as a0, InitService as a1, type Invitation as a2, type LayoutCollection as a3, type LayoutPage as a4, LayoutService as a5, type Lead as a6, type ListMeta as a7, MeilisearchService as a8, type Member as a9, REDIRECT_GATEWAYS as aA, ReelsService as aB, RegionService as aC, type RejectedLine as aD, type Review as aE, type ReviewPage as aF, ReviewService as aG, type SearchDoc as aH, type SearchResult as aI, SearchService as aJ, SettingService as aK, type ShippingRate as aL, type SiteChrome as aM, type SiteFooter as aN, type SiteHeader as aO, type SocialLink as aP, StateService as aQ, type StoreProfile as aR, StoreService as aS, type StorefrontCategory as aT, type StorefrontMenu as aU, type StorefrontOrder as aV, type StorefrontProduct as aW, type ThemeSettings as aX, type ThemeSettingsResult as aY, UploadService as aZ, UserService as a_, type Menu as aa, type MenuItem as ab, MenuService as ac, type MenuSummary as ad, type Money as ae, NewsletterService as af, type Offer as ag, type OpeningHours as ah, type Order as ai, type OrderLine as aj, OrderService as ak, type PageLayout as al, PageService as am, type PaymentIntent as an, PaymentMethodService as ao, type Plugin as ap, PluginService as aq, PopularSearchService as ar, PopularityService as as, type Postcode as at, type Product as au, type ProductFacets as av, type ProductOption as aw, ProductService as ax, ProfileService as ay, type Quote as az, AddressService as b, setRequestHost as b$, type VariantImage as b0, VariantService as b1, VarniCustomDesignService as b2, VarniCustomProductService as b3, type Vendor as b4, VendorService as b5, WarrantyService as b6, type Wishlist as b7, type WishlistItem as b8, WishlistService as b9, galleryService as bA, homeService as bB, initService as bC, layoutService as bD, mediaUrl as bE, meilisearchService as bF, menuService as bG, minorToMajor as bH, newsletterService as bI, orderService as bJ, ownDomain as bK, pageService as bL, paymentMethodService as bM, pluginService as bN, pluginsService as bO, popularSearchService as bP, popularityService as bQ, priceOf as bR, productImages as bS, productService as bT, productVideos as bU, profileService as bV, qs as bW, reelsService as bX, regionService as bY, reviewService as bZ, searchService as b_, addressService as ba, authService as bb, autocompleteService as bc, b2bService as bd, bannerService as be, blogService as bf, cartService as bg, categoryService as bh, chatService as bi, checkoutService as bj, collectionService as bk, contactService as bl, countryService as bm, couponService as bn, currencyExponent as bo, currencyService as bp, dealService as bq, demoRequestService as br, emptyCart as bs, emptyPage as bt, enquiryService as bu, faqService as bv, feedbackService as bw, fromEngineAddress as bx, fromIdentityAddress as by, fromSearchDoc as bz, type AppliedDiscount as c, settingService as c0, settingsService as c1, stateService as c2, staticStore as c3, storeForHost as c4, storeService as c5, toAddOn as c6, toCart as c7, toCartLine as c8, toCartOffer as c9, toCategory as ca, toCmsPage as cb, toCollection as cc, toEngineAddress as cd, toFreeShipping as ce, toIdentityAddress as cf, toMajor as cg, toMinor as ch, toOrder as ci, toPage as cj, toProduct as ck, toRating as cl, toStorefrontFacets as cm, toUser as cn, toVariant as co, toVendor as cp, uploadService as cq, userService as cr, variantService as cs, varniCustomDesignService as ct, varniCustomProductService as cu, vendorService as cv, warrantyService as cw, wishlistService as cx, type Approval as d, type AuthResponse as e, AuthService as f, AutocompleteService as g, type B2bRole as h, B2bService as i, BannerService as j, BaseService as k, BlogService as l, type CartLine as m, type CartOffer as n, CartService as o, CatalogService as p, type Category as q, CategoryService as r, ChatService as s, type CheckoutOptions as t, type CheckoutResult as u, CheckoutService as v, type CmsPage as w, type Collection as x, CollectionService as y, type Company as z };
7700
+ export { type GoogleReviews as $, type AddOn as A, type B2bPlaced as B, type Cart as C, type CompanyOrder as D, ContactService as E, CountryService as F, CouponService as G, type Credentials as H, type Credit as I, CurrencyService as J, type Customer as K, DealService as L, DemoRequestService as M, type EngineRequest as N, EnquiryService as O, type Envelope as P, type FacetValue as Q, type Faq as R, FaqService as S, FeedbackService as T, type FooterSettings as U, type FreeShipping as V, type Fulfillment as W, GalleryService as X, type GooglePlace as Y, type GoogleReview as Z, GoogleReviewService as _, type Address as a, type StorefrontProduct as a$, type GoogleSurvey as a0, type HeaderSettings as a1, type HomeLayout as a2, type HomeLayoutSection as a3, HomeService as a4, type IdentityAddress as a5, InitService as a6, type Invitation as a7, type LayoutCollection as a8, type LayoutPage as a9, type ProductFacets as aA, type ProductOption as aB, ProductService as aC, ProfileService as aD, type Quote as aE, REDIRECT_GATEWAYS as aF, ReelsService as aG, RegionService as aH, type RejectedLine as aI, type Review as aJ, type ReviewPage as aK, ReviewService as aL, type SearchDoc as aM, type SearchResult as aN, SearchService as aO, SettingService as aP, type ShippingRate as aQ, type SiteChrome as aR, type SiteFooter as aS, type SiteHeader as aT, type SocialLink as aU, StateService as aV, type StoreProfile as aW, StoreService as aX, type StorefrontCategory as aY, type StorefrontMenu as aZ, type StorefrontOrder as a_, LayoutService as aa, type Lead as ab, type ListMeta as ac, MeilisearchService as ad, type Member as ae, type Menu as af, type MenuItem as ag, MenuService as ah, type MenuSummary as ai, type Money as aj, NewsletterService as ak, type Offer as al, type OpeningHours as am, type Order as an, type OrderLine as ao, OrderService as ap, type PageLayout as aq, PageService as ar, type PaymentIntent as as, PaymentMethodService as at, type Plugin as au, PluginService as av, PopularSearchService as aw, PopularityService as ax, type Postcode as ay, type Product as az, AddressService as b, profileService as b$, type ThemeSettings as b0, type ThemeSettingsResult as b1, UploadService as b2, UserService as b3, type Variant as b4, type VariantImage as b5, VariantService as b6, VarniCustomDesignService as b7, VarniCustomProductService as b8, type Vendor as b9, faqService as bA, feedbackService as bB, fromEngineAddress as bC, fromIdentityAddress as bD, fromSearchDoc as bE, galleryService as bF, googleReviewService as bG, homeService as bH, initService as bI, layoutService as bJ, mediaUrl as bK, meilisearchService as bL, menuService as bM, minorToMajor as bN, newsletterService as bO, orderService as bP, ownDomain as bQ, pageService as bR, paymentMethodService as bS, pluginService as bT, pluginsService as bU, popularSearchService as bV, popularityService as bW, priceOf as bX, productImages as bY, productService as bZ, productVideos as b_, VendorService as ba, WarrantyService as bb, type Wishlist as bc, type WishlistItem as bd, WishlistService as be, addressService as bf, authService as bg, autocompleteService as bh, b2bService as bi, bannerService as bj, blogService as bk, cartService as bl, categoryService as bm, chatService as bn, checkoutService as bo, collectionService as bp, contactService as bq, countryService as br, couponService as bs, currencyExponent as bt, currencyService as bu, dealService as bv, demoRequestService as bw, emptyCart as bx, emptyPage as by, enquiryService as bz, type AppliedDiscount as c, qs as c0, reelsService as c1, regionService as c2, reviewService as c3, searchService as c4, setRequestHost as c5, settingService as c6, settingsService as c7, stateService as c8, staticStore as c9, varniCustomProductService as cA, vendorService as cB, warrantyService as cC, wishlistService as cD, storeForHost as ca, storeService as cb, toAddOn as cc, toCart as cd, toCartLine as ce, toCartOffer as cf, toCategory as cg, toCmsPage as ch, toCollection as ci, toEngineAddress as cj, toFreeShipping as ck, toIdentityAddress as cl, toMajor as cm, toMinor as cn, toOrder as co, toPage as cp, toProduct as cq, toRating as cr, toStorefrontFacets as cs, toUser as ct, toVariant as cu, toVendor as cv, uploadService as cw, userService as cx, variantService as cy, varniCustomDesignService as cz, type Approval as d, type AuthResponse as e, AuthService as f, AutocompleteService as g, type B2bRole as h, B2bService as i, BannerService as j, BaseService as k, BlogService as l, type CartLine as m, type CartOffer as n, CartService as o, CatalogService as p, type Category as q, CategoryService as r, ChatService as s, type CheckoutOptions as t, type CheckoutResult as u, CheckoutService as v, type CmsPage as w, type Collection as x, CollectionService as y, type Company as z };
@@ -418,6 +418,36 @@ type Plugin = {
418
418
  title: string;
419
419
  settings: Record<string, unknown>;
420
420
  };
421
+ /** `GET /x/google-reviews/place` (ext/google-reviews): Google's answer just now, never stored. */
422
+ type GooglePlace = {
423
+ rating: number;
424
+ user_rating_count: number;
425
+ google_maps_uri: string;
426
+ reviews: {
427
+ author: {
428
+ name: string;
429
+ uri?: string;
430
+ photo_uri?: string;
431
+ };
432
+ rating: number;
433
+ text?: string;
434
+ language?: string;
435
+ relative_time?: string;
436
+ publish_time?: string;
437
+ visit_date?: string;
438
+ google_maps_uri?: string;
439
+ flag_uri?: string;
440
+ }[];
441
+ };
442
+ /** `GET /x/google-reviews/survey/{number}`: Google Customer Reviews' opt-in fields, from the order. */
443
+ type GoogleSurvey = {
444
+ merchant_id: number;
445
+ order_id: string;
446
+ email: string;
447
+ delivery_country: string;
448
+ estimated_delivery_date: string;
449
+ opt_in_style?: string;
450
+ };
421
451
  /** `GET /api/store`: what anyone may read about the shop. */
422
452
  type StoreProfile = {
423
453
  name: string;
@@ -685,10 +715,14 @@ type CartExtras = {
685
715
  currency: string;
686
716
  } | null;
687
717
  discount?: AppliedDiscount | null;
688
- /** The Idempotency-Key of the last checkout attempt, and the body it was sent with. */
718
+ /**
719
+ * The Idempotency-Key of the last checkout attempt, the body it was sent with, and where
720
+ * Meta's pixel ran then, which a retry sends again unchanged.
721
+ */
689
722
  attempt?: {
690
723
  key: string;
691
724
  body: string;
725
+ meta?: Record<string, string>;
692
726
  } | null;
693
727
  };
694
728
 
@@ -6150,6 +6184,60 @@ declare class ReviewService extends BaseService {
6150
6184
  }
6151
6185
  declare const reviewService: ReviewService;
6152
6186
 
6187
+ /** A Google review with what Google's attribution policy asks a storefront to show. */
6188
+ type GoogleReview = {
6189
+ author: string;
6190
+ /** The author's Google profile and photo; https or empty. */
6191
+ authorUrl: string;
6192
+ authorPhoto: string;
6193
+ rating: number;
6194
+ /** The reviewer's own words, in their language. Empty for a rating with no words. */
6195
+ text: string;
6196
+ language: string;
6197
+ /** Google's own words for when, such as "a month ago". */
6198
+ when: string;
6199
+ /** YYYY-MM, when Google has one. */
6200
+ visited: string;
6201
+ /** The review on Google Maps, and where to report it to Google. */
6202
+ url: string;
6203
+ reportUrl: string;
6204
+ };
6205
+ type GoogleReviews = {
6206
+ /** Google's own rating and count, never worked out from `reviews`. */
6207
+ rating: number;
6208
+ count: number;
6209
+ /** Every review, on Google Maps: `reviews` are at most five of them. */
6210
+ mapsUrl: string;
6211
+ reviews: GoogleReview[];
6212
+ };
6213
+ /**
6214
+ * The store's Google reviews and Google Customer Reviews (ext/google-reviews).
6215
+ *
6216
+ * Both calls answer null when there is nothing to show — the plugin or its
6217
+ * switch off, Google refusing, the day's lookups spent — because each is an
6218
+ * extra on a page that must render without it.
6219
+ */
6220
+ declare class GoogleReviewService extends BaseService {
6221
+ private readonly facts;
6222
+ /**
6223
+ * Google's rating and its most relevant reviews, read live. Google's terms
6224
+ * forbid keeping them, so nothing here caches them either, and every call
6225
+ * is one the store pays Google for: call it when the section is in view.
6226
+ */
6227
+ place(): Promise<GoogleReviews | null>;
6228
+ /**
6229
+ * What Google Customer Reviews' opt-in is rendered with, for an order placed
6230
+ * in this browser: its access token is kept here, and nowhere else can ask.
6231
+ * Every field is the order's own; the keys are Google's, to pass unchanged
6232
+ * to `gapi.surveyoptin.render`.
6233
+ */
6234
+ survey(orderNumber: string): Promise<GoogleSurvey | null>;
6235
+ private switchOn;
6236
+ /** Off, used up for the day, or refused by Google: nothing to show. Anything else still throws. */
6237
+ private orNull;
6238
+ }
6239
+ declare const googleReviewService: GoogleReviewService;
6240
+
6153
6241
  type StorefrontMenu = {
6154
6242
  menuId: string;
6155
6243
  name: string;
@@ -7609,4 +7697,4 @@ declare class B2bService extends BaseService {
7609
7697
  }
7610
7698
  declare const b2bService: B2bService;
7611
7699
 
7612
- export { HomeService as $, type AddOn as A, type B2bPlaced as B, type Cart as C, type CompanyOrder as D, ContactService as E, CountryService as F, CouponService as G, type Credentials as H, type Credit as I, CurrencyService as J, type Customer as K, DealService as L, DemoRequestService as M, type EngineRequest as N, EnquiryService as O, type Envelope as P, type FacetValue as Q, type Faq as R, FaqService as S, FeedbackService as T, type FooterSettings as U, type FreeShipping as V, type Fulfillment as W, GalleryService as X, type HeaderSettings as Y, type HomeLayout as Z, type HomeLayoutSection as _, type Address as a, type Variant as a$, type IdentityAddress as a0, InitService as a1, type Invitation as a2, type LayoutCollection as a3, type LayoutPage as a4, LayoutService as a5, type Lead as a6, type ListMeta as a7, MeilisearchService as a8, type Member as a9, REDIRECT_GATEWAYS as aA, ReelsService as aB, RegionService as aC, type RejectedLine as aD, type Review as aE, type ReviewPage as aF, ReviewService as aG, type SearchDoc as aH, type SearchResult as aI, SearchService as aJ, SettingService as aK, type ShippingRate as aL, type SiteChrome as aM, type SiteFooter as aN, type SiteHeader as aO, type SocialLink as aP, StateService as aQ, type StoreProfile as aR, StoreService as aS, type StorefrontCategory as aT, type StorefrontMenu as aU, type StorefrontOrder as aV, type StorefrontProduct as aW, type ThemeSettings as aX, type ThemeSettingsResult as aY, UploadService as aZ, UserService as a_, type Menu as aa, type MenuItem as ab, MenuService as ac, type MenuSummary as ad, type Money as ae, NewsletterService as af, type Offer as ag, type OpeningHours as ah, type Order as ai, type OrderLine as aj, OrderService as ak, type PageLayout as al, PageService as am, type PaymentIntent as an, PaymentMethodService as ao, type Plugin as ap, PluginService as aq, PopularSearchService as ar, PopularityService as as, type Postcode as at, type Product as au, type ProductFacets as av, type ProductOption as aw, ProductService as ax, ProfileService as ay, type Quote as az, AddressService as b, setRequestHost as b$, type VariantImage as b0, VariantService as b1, VarniCustomDesignService as b2, VarniCustomProductService as b3, type Vendor as b4, VendorService as b5, WarrantyService as b6, type Wishlist as b7, type WishlistItem as b8, WishlistService as b9, galleryService as bA, homeService as bB, initService as bC, layoutService as bD, mediaUrl as bE, meilisearchService as bF, menuService as bG, minorToMajor as bH, newsletterService as bI, orderService as bJ, ownDomain as bK, pageService as bL, paymentMethodService as bM, pluginService as bN, pluginsService as bO, popularSearchService as bP, popularityService as bQ, priceOf as bR, productImages as bS, productService as bT, productVideos as bU, profileService as bV, qs as bW, reelsService as bX, regionService as bY, reviewService as bZ, searchService as b_, addressService as ba, authService as bb, autocompleteService as bc, b2bService as bd, bannerService as be, blogService as bf, cartService as bg, categoryService as bh, chatService as bi, checkoutService as bj, collectionService as bk, contactService as bl, countryService as bm, couponService as bn, currencyExponent as bo, currencyService as bp, dealService as bq, demoRequestService as br, emptyCart as bs, emptyPage as bt, enquiryService as bu, faqService as bv, feedbackService as bw, fromEngineAddress as bx, fromIdentityAddress as by, fromSearchDoc as bz, type AppliedDiscount as c, settingService as c0, settingsService as c1, stateService as c2, staticStore as c3, storeForHost as c4, storeService as c5, toAddOn as c6, toCart as c7, toCartLine as c8, toCartOffer as c9, toCategory as ca, toCmsPage as cb, toCollection as cc, toEngineAddress as cd, toFreeShipping as ce, toIdentityAddress as cf, toMajor as cg, toMinor as ch, toOrder as ci, toPage as cj, toProduct as ck, toRating as cl, toStorefrontFacets as cm, toUser as cn, toVariant as co, toVendor as cp, uploadService as cq, userService as cr, variantService as cs, varniCustomDesignService as ct, varniCustomProductService as cu, vendorService as cv, warrantyService as cw, wishlistService as cx, type Approval as d, type AuthResponse as e, AuthService as f, AutocompleteService as g, type B2bRole as h, B2bService as i, BannerService as j, BaseService as k, BlogService as l, type CartLine as m, type CartOffer as n, CartService as o, CatalogService as p, type Category as q, CategoryService as r, ChatService as s, type CheckoutOptions as t, type CheckoutResult as u, CheckoutService as v, type CmsPage as w, type Collection as x, CollectionService as y, type Company as z };
7700
+ export { type GoogleReviews as $, type AddOn as A, type B2bPlaced as B, type Cart as C, type CompanyOrder as D, ContactService as E, CountryService as F, CouponService as G, type Credentials as H, type Credit as I, CurrencyService as J, type Customer as K, DealService as L, DemoRequestService as M, type EngineRequest as N, EnquiryService as O, type Envelope as P, type FacetValue as Q, type Faq as R, FaqService as S, FeedbackService as T, type FooterSettings as U, type FreeShipping as V, type Fulfillment as W, GalleryService as X, type GooglePlace as Y, type GoogleReview as Z, GoogleReviewService as _, type Address as a, type StorefrontProduct as a$, type GoogleSurvey as a0, type HeaderSettings as a1, type HomeLayout as a2, type HomeLayoutSection as a3, HomeService as a4, type IdentityAddress as a5, InitService as a6, type Invitation as a7, type LayoutCollection as a8, type LayoutPage as a9, type ProductFacets as aA, type ProductOption as aB, ProductService as aC, ProfileService as aD, type Quote as aE, REDIRECT_GATEWAYS as aF, ReelsService as aG, RegionService as aH, type RejectedLine as aI, type Review as aJ, type ReviewPage as aK, ReviewService as aL, type SearchDoc as aM, type SearchResult as aN, SearchService as aO, SettingService as aP, type ShippingRate as aQ, type SiteChrome as aR, type SiteFooter as aS, type SiteHeader as aT, type SocialLink as aU, StateService as aV, type StoreProfile as aW, StoreService as aX, type StorefrontCategory as aY, type StorefrontMenu as aZ, type StorefrontOrder as a_, LayoutService as aa, type Lead as ab, type ListMeta as ac, MeilisearchService as ad, type Member as ae, type Menu as af, type MenuItem as ag, MenuService as ah, type MenuSummary as ai, type Money as aj, NewsletterService as ak, type Offer as al, type OpeningHours as am, type Order as an, type OrderLine as ao, OrderService as ap, type PageLayout as aq, PageService as ar, type PaymentIntent as as, PaymentMethodService as at, type Plugin as au, PluginService as av, PopularSearchService as aw, PopularityService as ax, type Postcode as ay, type Product as az, AddressService as b, profileService as b$, type ThemeSettings as b0, type ThemeSettingsResult as b1, UploadService as b2, UserService as b3, type Variant as b4, type VariantImage as b5, VariantService as b6, VarniCustomDesignService as b7, VarniCustomProductService as b8, type Vendor as b9, faqService as bA, feedbackService as bB, fromEngineAddress as bC, fromIdentityAddress as bD, fromSearchDoc as bE, galleryService as bF, googleReviewService as bG, homeService as bH, initService as bI, layoutService as bJ, mediaUrl as bK, meilisearchService as bL, menuService as bM, minorToMajor as bN, newsletterService as bO, orderService as bP, ownDomain as bQ, pageService as bR, paymentMethodService as bS, pluginService as bT, pluginsService as bU, popularSearchService as bV, popularityService as bW, priceOf as bX, productImages as bY, productService as bZ, productVideos as b_, VendorService as ba, WarrantyService as bb, type Wishlist as bc, type WishlistItem as bd, WishlistService as be, addressService as bf, authService as bg, autocompleteService as bh, b2bService as bi, bannerService as bj, blogService as bk, cartService as bl, categoryService as bm, chatService as bn, checkoutService as bo, collectionService as bp, contactService as bq, countryService as br, couponService as bs, currencyExponent as bt, currencyService as bu, dealService as bv, demoRequestService as bw, emptyCart as bx, emptyPage as by, enquiryService as bz, type AppliedDiscount as c, qs as c0, reelsService as c1, regionService as c2, reviewService as c3, searchService as c4, setRequestHost as c5, settingService as c6, settingsService as c7, stateService as c8, staticStore as c9, varniCustomProductService as cA, vendorService as cB, warrantyService as cC, wishlistService as cD, storeForHost as ca, storeService as cb, toAddOn as cc, toCart as cd, toCartLine as ce, toCartOffer as cf, toCategory as cg, toCmsPage as ch, toCollection as ci, toEngineAddress as cj, toFreeShipping as ck, toIdentityAddress as cl, toMajor as cm, toMinor as cn, toOrder as co, toPage as cp, toProduct as cq, toRating as cr, toStorefrontFacets as cs, toUser as ct, toVariant as cu, toVendor as cv, uploadService as cw, userService as cx, variantService as cy, varniCustomDesignService as cz, type Approval as d, type AuthResponse as e, AuthService as f, AutocompleteService as g, type B2bRole as h, B2bService as i, BannerService as j, BaseService as k, BlogService as l, type CartLine as m, type CartOffer as n, CartService as o, CatalogService as p, type Category as q, CategoryService as r, ChatService as s, type CheckoutOptions as t, type CheckoutResult as u, CheckoutService as v, type CmsPage as w, type Collection as x, CollectionService as y, type Company as z };
package/dist/index.cjs CHANGED
@@ -236,6 +236,17 @@ function currentMe() {
236
236
  return null;
237
237
  }
238
238
  }
239
+ function metaBrowser() {
240
+ const fbp = readCookie("_fbp");
241
+ if (!fbp || typeof window.fbq !== "function") return void 0;
242
+ const fbc = readCookie("_fbc");
243
+ return {
244
+ fbp,
245
+ ...fbc ? { fbc } : {},
246
+ client_user_agent: window.navigator.userAgent,
247
+ event_source_url: window.location.origin + window.location.pathname
248
+ };
249
+ }
239
250
  function storedCartId() {
240
251
  const v = readLocal("cart_id");
241
252
  if (!v || v === "undefined" || v === "null") return null;
@@ -2207,11 +2218,13 @@ var CheckoutService = class extends BaseService {
2207
2218
  ...extra
2208
2219
  };
2209
2220
  const serialised = JSON.stringify(body);
2210
- const key = extras.attempt?.body === `${code}:${serialised}` ? extras.attempt.key : newKey();
2211
- saveCartExtras(id2, { attempt: { key, body: `${code}:${serialised}` } });
2221
+ const retry = extras.attempt?.body === `${code}:${serialised}`;
2222
+ const key = retry ? extras.attempt.key : newKey();
2223
+ const meta = retry ? extras.attempt?.meta : metaBrowser();
2224
+ saveCartExtras(id2, { attempt: { key, body: `${code}:${serialised}`, ...meta ? { meta } : {} } });
2212
2225
  const result = await this.data(`/api/checkout/${encodeURIComponent(code)}`, {
2213
2226
  method: "POST",
2214
- body,
2227
+ body: meta ? { ...body, metadata: { ...extra.metadata, meta_capi: meta } } : body,
2215
2228
  headers: { "Idempotency-Key": key }
2216
2229
  });
2217
2230
  if (result.order.access_token) {
@@ -2873,6 +2886,71 @@ var ReviewService = class extends BaseService {
2873
2886
  };
2874
2887
  var reviewService = new ReviewService();
2875
2888
 
2889
+ // src/services/google-review-service.ts
2890
+ var PLUGIN = "google-reviews";
2891
+ var GoogleReviewService = class extends BaseService {
2892
+ facts = new StoreFacts(this._fetch);
2893
+ /**
2894
+ * Google's rating and its most relevant reviews, read live. Google's terms
2895
+ * forbid keeping them, so nothing here caches them either, and every call
2896
+ * is one the store pays Google for: call it when the section is in view.
2897
+ */
2898
+ async place() {
2899
+ if (!await this.switchOn("show_place")) return null;
2900
+ const p = await this.orNull(() => this.data("/x/google-reviews/place"));
2901
+ if (!p?.user_rating_count) return null;
2902
+ return {
2903
+ rating: p.rating,
2904
+ count: p.user_rating_count,
2905
+ mapsUrl: p.google_maps_uri ?? "",
2906
+ reviews: (p.reviews ?? []).map((r) => ({
2907
+ author: r.author?.name ?? "",
2908
+ authorUrl: r.author?.uri ?? "",
2909
+ authorPhoto: r.author?.photo_uri ?? "",
2910
+ rating: r.rating,
2911
+ text: r.text ?? "",
2912
+ language: r.language ?? "",
2913
+ when: r.relative_time ?? "",
2914
+ visited: r.visit_date ?? "",
2915
+ url: r.google_maps_uri ?? "",
2916
+ reportUrl: r.flag_uri ?? ""
2917
+ }))
2918
+ };
2919
+ }
2920
+ /**
2921
+ * What Google Customer Reviews' opt-in is rendered with, for an order placed
2922
+ * in this browser: its access token is kept here, and nowhere else can ask.
2923
+ * Every field is the order's own; the keys are Google's, to pass unchanged
2924
+ * to `gapi.surveyoptin.render`.
2925
+ */
2926
+ async survey(orderNumber) {
2927
+ const kept = orderNumber ? placedOrder(orderNumber) : void 0;
2928
+ if (!kept || !await this.switchOn("customer_reviews")) return null;
2929
+ return this.orNull(
2930
+ () => this.data(`/x/google-reviews/survey/${encodeURIComponent(orderNumber)}`, {
2931
+ query: { token: kept.token }
2932
+ })
2933
+ );
2934
+ }
2935
+ async switchOn(setting) {
2936
+ try {
2937
+ return (await this.facts.plugins()).get(PLUGIN)?.settings?.[setting] === true;
2938
+ } catch {
2939
+ return false;
2940
+ }
2941
+ }
2942
+ /** Off, used up for the day, or refused by Google: nothing to show. Anything else still throws. */
2943
+ async orNull(call) {
2944
+ try {
2945
+ return await call();
2946
+ } catch (err) {
2947
+ if (err instanceof GoCommerceError && [404, 429, 502].includes(err.status)) return null;
2948
+ throw err;
2949
+ }
2950
+ }
2951
+ };
2952
+ var googleReviewService = new GoogleReviewService();
2953
+
2876
2954
  // src/services/menu-service.ts
2877
2955
  function linkFor(item) {
2878
2956
  const t = item.target ?? "";
@@ -3091,9 +3169,21 @@ var StoreService = class extends BaseService {
3091
3169
  ...basePlugins.isProductReviewsAndRatings,
3092
3170
  ...flag(plugins.has("product-reviews"))
3093
3171
  },
3172
+ // Google Customer Reviews (ext/google-reviews): the confirmation page's survey offer,
3173
+ // whose fields the engine builds from the order, and Google's store widget, which
3174
+ // belongs to the same programme and so needs the survey on.
3175
+ googleReviewsOptIn: {
3176
+ ...basePlugins.googleReviewsOptIn,
3177
+ ...flag(googleSetting(plugins, "customer_reviews") === true)
3178
+ },
3179
+ googleStoreWidget: storeWidget(plugins),
3094
3180
  // The footer's sign-up box posts to ext/newsletter, and the theme editor's footer
3095
3181
  // switch (D131) can only show it while that is on.
3096
3182
  newsletter: { ...basePlugins.newsletter, ...flag(plugins.has("newsletter")) },
3183
+ // The ad and analytics tags (D160). The engine decides, not the static record:
3184
+ // one storefront serves every store, and one store's pixel must never
3185
+ // load on another's pages.
3186
+ ...adTags(plugins),
3097
3187
  // Discount codes are core: every GoCommerce store takes them, so
3098
3188
  // the code box is shown whatever the static record says.
3099
3189
  isDiscountCoupons: { ...basePlugins.isDiscountCoupons, active: true },
@@ -3119,6 +3209,22 @@ var StoreService = class extends BaseService {
3119
3209
  }
3120
3210
  };
3121
3211
  var storeService = new StoreService();
3212
+ var AD_TAGS = [
3213
+ ["meta-pixel", "pixel_id", "facebookPixel"],
3214
+ ["microsoft-clarity", "project_id", "microsoftClarity"],
3215
+ ["hotjar", "site_id", "hotjar"],
3216
+ ["tiktok-pixel", "pixel_id", "tiktokPixel"],
3217
+ ["pinterest-tag", "tag_id", "pinterestTag"],
3218
+ ["snapchat-pixel", "pixel_id", "snapchatPixel"]
3219
+ ];
3220
+ function adTags(plugins) {
3221
+ return Object.fromEntries(
3222
+ AD_TAGS.map(([key, field, name]) => {
3223
+ const id2 = String(plugins.get(key)?.settings?.[field] ?? "").trim();
3224
+ return [name, id2 ? { active: true, id: id2 } : { active: false }];
3225
+ })
3226
+ );
3227
+ }
3122
3228
  function deliverable(base, ships) {
3123
3229
  if (ships.everywhere || !ships.countries.length) return {};
3124
3230
  const known = new Map((base.countries ?? []).map((c) => [String(c.code).toUpperCase(), c]));
@@ -3133,6 +3239,12 @@ function regionName(code) {
3133
3239
  return code;
3134
3240
  }
3135
3241
  }
3242
+ var googleSetting = (plugins, key) => plugins.get("google-reviews")?.settings?.[key];
3243
+ function storeWidget(plugins) {
3244
+ const where = googleSetting(plugins, "store_widget");
3245
+ if (googleSetting(plugins, "customer_reviews") !== true || !where) return { active: false };
3246
+ return { active: true, position: where === "Bottom left" ? "LEFT_BOTTOM" : "RIGHT_BOTTOM" };
3247
+ }
3136
3248
  var LOGIN_TYPES = { phone_otp: "PHONE", email_or_phone: "BOTH", email_password: "EMAIL" };
3137
3249
 
3138
3250
  // src/services/page-service.ts
@@ -3839,6 +3951,7 @@ exports.FaqService = FaqService;
3839
3951
  exports.FeedbackService = FeedbackService;
3840
3952
  exports.GalleryService = GalleryService;
3841
3953
  exports.GoCommerceError = GoCommerceError;
3954
+ exports.GoogleReviewService = GoogleReviewService;
3842
3955
  exports.HomeService = HomeService;
3843
3956
  exports.InitService = InitService;
3844
3957
  exports.LayoutService = LayoutService;
@@ -3901,6 +4014,7 @@ exports.fromEngineAddress = fromEngineAddress;
3901
4014
  exports.fromIdentityAddress = fromIdentityAddress;
3902
4015
  exports.fromSearchDoc = fromSearchDoc;
3903
4016
  exports.galleryService = galleryService;
4017
+ exports.googleReviewService = googleReviewService;
3904
4018
  exports.hasStaticStore = hasStaticStore;
3905
4019
  exports.homeService = homeService;
3906
4020
  exports.initService = initService;