@shoppexio/storefront-react 0.1.3 → 0.1.5
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/CHANGELOG.md +18 -0
- package/README.md +1 -1
- package/dist/account.js +93 -58
- package/dist/account.js.map +1 -1
- package/dist/index.d.ts +102 -11
- package/dist/index.js +94 -19
- package/dist/index.js.map +1 -1
- package/eject/account/account-page.tsx +8 -2
- package/eject/account/account-warranties.ts +9 -0
- package/eject/account/messages/ar.json +2 -1
- package/eject/account/messages/de.json +2 -1
- package/eject/account/messages/en.json +2 -1
- package/eject/account/messages/es.json +2 -1
- package/eject/account/messages/fi.json +2 -1
- package/eject/account/messages/fr.json +2 -1
- package/eject/account/messages/hi.json +2 -1
- package/eject/account/messages/it.json +2 -1
- package/eject/account/messages/lt.json +2 -1
- package/eject/account/messages/nl.json +2 -1
- package/eject/account/messages/pl.json +2 -1
- package/eject/account/messages/pt.json +2 -1
- package/eject/account/messages/ru.json +2 -1
- package/eject/account/messages/tr.json +2 -1
- package/eject/account/messages/uk.json +2 -1
- package/eject/account/messages/zh.json +2 -1
- package/eject/account/orders.tsx +6 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -826,10 +826,16 @@ interface ShoppexSdk {
|
|
|
826
826
|
data?: SdkPage[];
|
|
827
827
|
message?: string;
|
|
828
828
|
}>;
|
|
829
|
+
/**
|
|
830
|
+
* On a failure, `status` is the HTTP status (404 for a page that does not
|
|
831
|
+
* exist) and is absent when the request never reached a server. SDK 1.0.87
|
|
832
|
+
* and later; earlier builds send no `status` at all.
|
|
833
|
+
*/
|
|
829
834
|
getPage(slug: string): Promise<{
|
|
830
835
|
success: boolean;
|
|
831
836
|
data?: SdkPage;
|
|
832
837
|
message?: string;
|
|
838
|
+
status?: number;
|
|
833
839
|
}>;
|
|
834
840
|
/** Merchant-configured navigation menus, keyed by slot (header/footer/…). */
|
|
835
841
|
getMenus(): Promise<{
|
|
@@ -896,7 +902,9 @@ interface ShoppexSdk {
|
|
|
896
902
|
* One page of the same feed, newest first. `cursor` is the previous page's
|
|
897
903
|
* `pagination.next_cursor`; omit it for the first page.
|
|
898
904
|
*/
|
|
899
|
-
getShopReviewsPage(cursor?: string | null
|
|
905
|
+
getShopReviewsPage(cursor?: string | null, options?: {
|
|
906
|
+
product?: string | null;
|
|
907
|
+
}): Promise<{
|
|
900
908
|
success: boolean;
|
|
901
909
|
data?: {
|
|
902
910
|
feedback: SdkShopReview[];
|
|
@@ -904,7 +912,16 @@ interface ShoppexSdk {
|
|
|
904
912
|
next_cursor: string | null;
|
|
905
913
|
has_more: boolean;
|
|
906
914
|
};
|
|
915
|
+
/** Counts over the whole list, or over one product's reviews when filtered. */
|
|
916
|
+
summary?: SdkShopReviewsSummary;
|
|
917
|
+
/**
|
|
918
|
+
* The product filter the API applied, echoed back. Absent from an API that
|
|
919
|
+
* predates the filter and ignored it; see `loadShopReviewsPage`.
|
|
920
|
+
*/
|
|
921
|
+
product?: string | null;
|
|
907
922
|
};
|
|
923
|
+
message?: string;
|
|
924
|
+
status?: number;
|
|
908
925
|
}>;
|
|
909
926
|
/** Starts an in-page sign-in. Sends the email and nothing else. */
|
|
910
927
|
requestOtp(email: string): Promise<SdkResponse<unknown>>;
|
|
@@ -1054,6 +1071,14 @@ interface ShoppexSdk {
|
|
|
1054
1071
|
/** Lists the buyer's reseller API keys without plaintext secrets. */
|
|
1055
1072
|
resellerApiKeys(): Promise<SdkResponse<unknown>>;
|
|
1056
1073
|
}
|
|
1074
|
+
interface SdkShopReviewsSummary {
|
|
1075
|
+
total: number;
|
|
1076
|
+
positive: number;
|
|
1077
|
+
neutral: number;
|
|
1078
|
+
negative: number;
|
|
1079
|
+
/** 1-5 average of the scores (5/3/1), null for an empty list. */
|
|
1080
|
+
average_score: number | null;
|
|
1081
|
+
}
|
|
1057
1082
|
interface SdkShopReview {
|
|
1058
1083
|
id: string;
|
|
1059
1084
|
/** 1-5, normalized by the SDK from the shop-feedback score (5/3/1). */
|
|
@@ -2534,6 +2559,14 @@ interface GroupCardModel {
|
|
|
2534
2559
|
price: number;
|
|
2535
2560
|
}
|
|
2536
2561
|
type CatalogCardModel = ProductCardModel | GroupCardModel;
|
|
2562
|
+
/**
|
|
2563
|
+
* A card is sold out when nothing on it can be ordered: no stock at all, or no
|
|
2564
|
+
* option whose effective quantity range is non-empty (`quantity_min` 2 against
|
|
2565
|
+
* one unit left). PAYMENT PATH: the card's quick add goes through `add()`,
|
|
2566
|
+
* which refuses exactly these selections, so an active button here would be a
|
|
2567
|
+
* control that silently does nothing.
|
|
2568
|
+
*/
|
|
2569
|
+
declare function isCardSoldOut(product: StorefrontProduct): boolean;
|
|
2537
2570
|
interface StorefrontCatalog {
|
|
2538
2571
|
cards: CatalogCardModel[];
|
|
2539
2572
|
categories: StorefrontCategory[];
|
|
@@ -2880,6 +2913,8 @@ interface ShopReview {
|
|
|
2880
2913
|
productTitle: string | null;
|
|
2881
2914
|
/** True when the review is tied to a real completed purchase. */
|
|
2882
2915
|
verified: boolean;
|
|
2916
|
+
/** Left by the shop's review automation, not written by the buyer. */
|
|
2917
|
+
automated: boolean;
|
|
2883
2918
|
}
|
|
2884
2919
|
type ShopReviewsState = {
|
|
2885
2920
|
status: 'loading';
|
|
@@ -2917,14 +2952,62 @@ declare function toShopReviews(rows: readonly SdkShopReview[], labels: ShopRevie
|
|
|
2917
2952
|
* derive a number from them.
|
|
2918
2953
|
*/
|
|
2919
2954
|
declare function reviewsForProduct(reviews: readonly ShopReview[], productTitle: string): ShopReview[];
|
|
2955
|
+
/** One page of the shop's reviews, newest first. */
|
|
2956
|
+
interface ShopReviewsPageResult {
|
|
2957
|
+
reviews: ShopReview[];
|
|
2958
|
+
/** Pass to the next call; null on the last page. */
|
|
2959
|
+
nextCursor: string | null;
|
|
2960
|
+
/** Counts over the whole list (or the product's reviews), null when the API sent none. */
|
|
2961
|
+
summary: SdkShopReviewsSummary | null;
|
|
2962
|
+
}
|
|
2963
|
+
/**
|
|
2964
|
+
* One page of reviews from the feed, optionally for one product (its catalog
|
|
2965
|
+
* `id`). Throws when the request fails.
|
|
2966
|
+
*
|
|
2967
|
+
* A product page must never show another product's reviews, so a filtered
|
|
2968
|
+
* request also requires the API to echo the filter back: an API that predates
|
|
2969
|
+
* `product` ignores it and would answer with the whole shop's list.
|
|
2970
|
+
*/
|
|
2971
|
+
declare function loadShopReviewsPage(options: {
|
|
2972
|
+
cursor?: string | null;
|
|
2973
|
+
product?: string | null;
|
|
2974
|
+
labels: ShopReviewLabels;
|
|
2975
|
+
}): Promise<ShopReviewsPageResult>;
|
|
2920
2976
|
/**
|
|
2921
2977
|
* The newest WRITTEN reviews, at most `limit`, for a sample such as a home
|
|
2922
|
-
* section. Pages through the feed only until it has
|
|
2923
|
-
*
|
|
2924
|
-
*
|
|
2925
|
-
|
|
2978
|
+
* section or a product's review tab. Pages through the feed only until it has
|
|
2979
|
+
* enough. Automated entries and ratings without words are skipped, since a
|
|
2980
|
+
* sample of quotes needs quotes. Resolves null when a page request fails.
|
|
2981
|
+
*/
|
|
2982
|
+
declare function loadLatestWrittenReviews(limit: number, labels: ShopReviewLabels, options?: {
|
|
2983
|
+
product?: string | null;
|
|
2984
|
+
}): Promise<ShopReview[] | null>;
|
|
2985
|
+
type PagedShopReviewsState = {
|
|
2986
|
+
status: 'loading';
|
|
2987
|
+
} | {
|
|
2988
|
+
status: 'error';
|
|
2989
|
+
} | {
|
|
2990
|
+
status: 'ready';
|
|
2991
|
+
reviews: ShopReview[];
|
|
2992
|
+
summary: SdkShopReviewsSummary | null;
|
|
2993
|
+
hasMore: boolean;
|
|
2994
|
+
/** True while the next page is on its way. */
|
|
2995
|
+
loadingMore: boolean;
|
|
2996
|
+
/** Set when the NEXT page failed; the pages already shown stay. */
|
|
2997
|
+
moreFailed: boolean;
|
|
2998
|
+
};
|
|
2999
|
+
/**
|
|
3000
|
+
* The shop's reviews, one page at a time: the first page on mount (or when
|
|
3001
|
+
* `product` changes), the next only when `loadMore` is called. The summary is
|
|
3002
|
+
* the API's, so the score and breakdown describe the whole list, not the pages
|
|
3003
|
+
* loaded so far.
|
|
2926
3004
|
*/
|
|
2927
|
-
declare function
|
|
3005
|
+
declare function usePagedShopReviews(options: {
|
|
3006
|
+
product?: string | null;
|
|
3007
|
+
labels: ShopReviewLabels;
|
|
3008
|
+
}): PagedShopReviewsState & {
|
|
3009
|
+
loadMore: () => void;
|
|
3010
|
+
};
|
|
2928
3011
|
declare function averageRating(reviews: readonly ShopReview[]): number | null;
|
|
2929
3012
|
declare function useShopReviews(labels: ShopReviewLabels): ShopReviewsState;
|
|
2930
3013
|
|
|
@@ -3025,16 +3108,24 @@ type ShopPageState = {
|
|
|
3025
3108
|
status: 'ready';
|
|
3026
3109
|
page: ShopPageModel;
|
|
3027
3110
|
}
|
|
3028
|
-
/** The
|
|
3111
|
+
/** The API answered that no such page exists (404), or the page has no name. */
|
|
3029
3112
|
| {
|
|
3030
3113
|
status: 'missing';
|
|
3114
|
+
}
|
|
3115
|
+
/**
|
|
3116
|
+
* The page could not be loaded: the API failed or could not be reached, or
|
|
3117
|
+
* the page's body could not be rendered. Not "missing": the page may exist.
|
|
3118
|
+
*/
|
|
3119
|
+
| {
|
|
3120
|
+
status: 'error';
|
|
3031
3121
|
};
|
|
3032
3122
|
/**
|
|
3033
3123
|
* Loads one CMS page by slug.
|
|
3034
3124
|
*
|
|
3035
|
-
*
|
|
3036
|
-
*
|
|
3037
|
-
*
|
|
3125
|
+
* `missing` only when the API says so (404) or the page it returns has no name
|
|
3126
|
+
* to show; inventing a title from the slug would publish a heading the merchant
|
|
3127
|
+
* never wrote. Any other failure is `error`, so an outage never tells a buyer a
|
|
3128
|
+
* real page does not exist.
|
|
3038
3129
|
*/
|
|
3039
3130
|
declare function loadShopPage(slug: string): Promise<ShopPageState>;
|
|
3040
3131
|
|
|
@@ -3115,4 +3206,4 @@ declare function useOnlineUserCount(): number | null;
|
|
|
3115
3206
|
*/
|
|
3116
3207
|
declare function resolveProductVideoEmbedSrc(value: unknown): string | null;
|
|
3117
3208
|
|
|
3118
|
-
export { ACCOUNT_ARTIFACT_CAPABILITIES, ACCOUNT_PATH, ACCOUNT_PATH_ALIAS, ACCOUNT_ROUTE_MESSAGE_KEYS, ACCOUNT_STOREFRONT_ROUTES, ACCOUNT_TABS, type AccountRouteMessageKey, type AccountRouteParts, type AccountTab, type AccountView, type BuyBoxVariantModel, CATALOG_PAGE_SIZE, CATALOG_SORTS, CATALOG_SORT_LABELS, type CartBoundsHeal, CartProvider, type CartQuoteLineBounds, type CartTotals, type CartView, type CartViewLine, type CatalogCardModel, type CatalogPage, type CatalogSort, type CheckoutFieldGroup, type CheckoutFieldValues, type CheckoutFields, type ContactFormValues, type ContactSubmissionContext, DEFAULT_ACCOUNT_TAB, DEFAULT_LOW_STOCK_THRESHOLD, DELIVERY_TIME_UNITS, type DeliveryPromise, type DeliveryTimeUnit, type GroupCardModel, IMPLEMENTED_ACCOUNT_TABS, type ImplementedAccountTab, type LicenseStatement, type LicenseTerm, type LinePricing, MAX_PAY_WHAT_YOU_WANT_PRICE, type MenuNavLink, type MenuSlot, type NavLink, type NavigationLinks, PRODUCT_BADGE_ICON_NAMES, type ProductAddon, type ProductAutomaticDeal, type ProductBadge, type ProductBadgeIconName, type ProductBundle, type ProductBundleItem, type ProductCardModel, type ProductCategoryRef, type ProductContentTab, type ProductCustomField, type ProductDetailModel, type ProductFaq, type ProductRatingModel, type ProductSubscription, type ProductType, QUOTE_UNAVAILABLE_CHECKOUT_ERROR, type RatingStars, type ResellerProgramSummary, type RewardProgramItem, type RewardProgramSummary, SERVING_CONTEXT_HINT, SHOP_REVIEW_PAGE_SIZE, STOREFRONT_SORT_KEYS, type SdkCartAddOptions, type SdkCartAddon, type SdkCartAppliedDiscount, type SdkCartCodeSource, type SdkCartItem, type SdkCartQuote, type SdkCartQuoteLine, type SdkCheckoutResult, type SdkCustomerAffiliateLink, type SdkCustomerAffiliateSummary, type SdkCustomerDashboard, type SdkCustomerDashboardOrder, type SdkCustomerDeliverable, type SdkCustomerDeliveryStatus, type SdkCustomerDeliverySummary, type SdkCustomerLicense, type SdkCustomerLoyalty, type SdkCustomerLoyaltyRedeem, type SdkCustomerLoyaltyTransactionType, type SdkCustomerOrderDetail, type SdkCustomerOrderPage, type SdkCustomerOrderSummary, type SdkCustomerRewardActivity, type SdkCustomerRewards, type SdkCustomerSubscription, type SdkCustomerTicketSummary, type SdkCustomerWarranty, type SdkCustomerWarrantyClaim, type SdkCustomerWarrantyClaimStatus, type SdkCustomerWarrantyList, type SdkCustomerWarrantyStatus, type SdkEligibleCartDeal, type SdkInitOptions, type SdkMenu, type SdkMenuItem, type SdkPage, type SdkRecentSaleEntry, type SdkResponse, type SdkShopReview, type ShopPageFaqItem, type ShopPageModel, type ShopPageState, type ShopReview, type ShopReviewLabels, type ShopReviewsState, type ShoppexSdk, type SocialLink, type SocialNetwork, type StockChip, type StockTone, type StorefrontAddon, type StorefrontCatalog, type StorefrontCategory, type StorefrontData, type StorefrontGroup, type StorefrontListingItem, type StorefrontPriceVariant, type StorefrontProduct, StorefrontProvider, type StorefrontSettings, type StorefrontShop, type StorefrontShopStats, type StorefrontSortKey, type SubscriptionIntervalUnit, type SupportChannel, type VolumeDiscountRule, accountOrderHref, accountRouteMessage, accountTabHref, accountTabLabelKey, averageRating, badgesForCard, badgesForProductPage, buildCartTotals, buildCartView, buildCustomFieldPayload, buildInitialCheckoutFieldValues, buildProductDetail, buildStorefrontCatalog, calculateDisplayLineTotal, calculateLinePricing, canonicalAccountPath, checkoutFieldKey, checkoutFieldWriteRepriced, checkoutNeedsDetails, clampQuantity, clearRecoveredQuoteCheckoutError, filterCatalogCards, findStorefrontProduct, firstOptionalString, flattenMerchantHtmlToText, formatCompactCount, formatDeliveryTime, formatLicenseTerm, formatMoney, formatSubscriptionCadence, formatSubscriptionTrial, getAuthoredContent, getBuyerCurrency, getProductGroups, getProducts, getShoppex, getStorefrontAddons, getStorefrontCategories, getStorefrontListing, getStorefrontSettings, getStorefrontShop, hasInjectedStorefrontData, isAccountTab, isBlankMerchantHtml, isCheckboxValueChecked, isImplementedAccountTab, isProductSoldOut, isRecord, isSelectionSoldOut, loadLatestWrittenReviews, loadShopPage, missingRequiredCheckoutValues, optionalBoolean, optionalString, optionalStringWithDefault, paginateCatalogCards, parseAccountPath, parseCartQuoteLines, parseEnum, parseFiniteNumber, parseProductBadges, parseStorefrontSortKey, readCheckoutNeedsDetails, readStorefrontData, requireArray, requireBoolean, requireNumber, requireRecord, requireString, requireStringFromKeys, requireUnknownRecord, resolveAccountView, resolveBadgeForeground, resolveCartBoundsHeals, resolveCategorySelection, resolveCheckoutFields, resolveDeliveryPromise, resolveDisplayStock, resolveHideStockCounter, resolveLicenseTerm, resolveMenuLinksForSlot, resolvePayWhatYouWantMinimum, resolveProductVideoEmbedSrc, resolveQuantityBounds, resolveSupportChannels, resolveUnsellableLineIds, resolveVariantStock, reviewsForProduct, roundCurrency, sanitizeMerchantHtml, sortCatalogCards, startCartMutation, stripMerchantHtmlImages, submitContactTicket, toShopReviews, toStarCount, useCart, useNavigationLinks, useOnlineUserCount, useShopReviews, useStorefront, validateCheckoutFieldValue, validateCheckoutFields, validateContactSubmission, withRequiredAddons };
|
|
3209
|
+
export { ACCOUNT_ARTIFACT_CAPABILITIES, ACCOUNT_PATH, ACCOUNT_PATH_ALIAS, ACCOUNT_ROUTE_MESSAGE_KEYS, ACCOUNT_STOREFRONT_ROUTES, ACCOUNT_TABS, type AccountRouteMessageKey, type AccountRouteParts, type AccountTab, type AccountView, type BuyBoxVariantModel, CATALOG_PAGE_SIZE, CATALOG_SORTS, CATALOG_SORT_LABELS, type CartBoundsHeal, CartProvider, type CartQuoteLineBounds, type CartTotals, type CartView, type CartViewLine, type CatalogCardModel, type CatalogPage, type CatalogSort, type CheckoutFieldGroup, type CheckoutFieldValues, type CheckoutFields, type ContactFormValues, type ContactSubmissionContext, DEFAULT_ACCOUNT_TAB, DEFAULT_LOW_STOCK_THRESHOLD, DELIVERY_TIME_UNITS, type DeliveryPromise, type DeliveryTimeUnit, type GroupCardModel, IMPLEMENTED_ACCOUNT_TABS, type ImplementedAccountTab, type LicenseStatement, type LicenseTerm, type LinePricing, MAX_PAY_WHAT_YOU_WANT_PRICE, type MenuNavLink, type MenuSlot, type NavLink, type NavigationLinks, PRODUCT_BADGE_ICON_NAMES, type PagedShopReviewsState, type ProductAddon, type ProductAutomaticDeal, type ProductBadge, type ProductBadgeIconName, type ProductBundle, type ProductBundleItem, type ProductCardModel, type ProductCategoryRef, type ProductContentTab, type ProductCustomField, type ProductDetailModel, type ProductFaq, type ProductRatingModel, type ProductSubscription, type ProductType, QUOTE_UNAVAILABLE_CHECKOUT_ERROR, type RatingStars, type ResellerProgramSummary, type RewardProgramItem, type RewardProgramSummary, SERVING_CONTEXT_HINT, SHOP_REVIEW_PAGE_SIZE, STOREFRONT_SORT_KEYS, type SdkCartAddOptions, type SdkCartAddon, type SdkCartAppliedDiscount, type SdkCartCodeSource, type SdkCartItem, type SdkCartQuote, type SdkCartQuoteLine, type SdkCheckoutResult, type SdkCustomerAffiliateLink, type SdkCustomerAffiliateSummary, type SdkCustomerDashboard, type SdkCustomerDashboardOrder, type SdkCustomerDeliverable, type SdkCustomerDeliveryStatus, type SdkCustomerDeliverySummary, type SdkCustomerLicense, type SdkCustomerLoyalty, type SdkCustomerLoyaltyRedeem, type SdkCustomerLoyaltyTransactionType, type SdkCustomerOrderDetail, type SdkCustomerOrderPage, type SdkCustomerOrderSummary, type SdkCustomerRewardActivity, type SdkCustomerRewards, type SdkCustomerSubscription, type SdkCustomerTicketSummary, type SdkCustomerWarranty, type SdkCustomerWarrantyClaim, type SdkCustomerWarrantyClaimStatus, type SdkCustomerWarrantyList, type SdkCustomerWarrantyStatus, type SdkEligibleCartDeal, type SdkInitOptions, type SdkMenu, type SdkMenuItem, type SdkPage, type SdkRecentSaleEntry, type SdkResponse, type SdkShopReview, type SdkShopReviewsSummary, type ShopPageFaqItem, type ShopPageModel, type ShopPageState, type ShopReview, type ShopReviewLabels, type ShopReviewsPageResult, type ShopReviewsState, type ShoppexSdk, type SocialLink, type SocialNetwork, type StockChip, type StockTone, type StorefrontAddon, type StorefrontCatalog, type StorefrontCategory, type StorefrontData, type StorefrontGroup, type StorefrontListingItem, type StorefrontPriceVariant, type StorefrontProduct, StorefrontProvider, type StorefrontSettings, type StorefrontShop, type StorefrontShopStats, type StorefrontSortKey, type SubscriptionIntervalUnit, type SupportChannel, type VolumeDiscountRule, accountOrderHref, accountRouteMessage, accountTabHref, accountTabLabelKey, averageRating, badgesForCard, badgesForProductPage, buildCartTotals, buildCartView, buildCustomFieldPayload, buildInitialCheckoutFieldValues, buildProductDetail, buildStorefrontCatalog, calculateDisplayLineTotal, calculateLinePricing, canonicalAccountPath, checkoutFieldKey, checkoutFieldWriteRepriced, checkoutNeedsDetails, clampQuantity, clearRecoveredQuoteCheckoutError, filterCatalogCards, findStorefrontProduct, firstOptionalString, flattenMerchantHtmlToText, formatCompactCount, formatDeliveryTime, formatLicenseTerm, formatMoney, formatSubscriptionCadence, formatSubscriptionTrial, getAuthoredContent, getBuyerCurrency, getProductGroups, getProducts, getShoppex, getStorefrontAddons, getStorefrontCategories, getStorefrontListing, getStorefrontSettings, getStorefrontShop, hasInjectedStorefrontData, isAccountTab, isBlankMerchantHtml, isCardSoldOut, isCheckboxValueChecked, isImplementedAccountTab, isProductSoldOut, isRecord, isSelectionSoldOut, loadLatestWrittenReviews, loadShopPage, loadShopReviewsPage, missingRequiredCheckoutValues, optionalBoolean, optionalString, optionalStringWithDefault, paginateCatalogCards, parseAccountPath, parseCartQuoteLines, parseEnum, parseFiniteNumber, parseProductBadges, parseStorefrontSortKey, readCheckoutNeedsDetails, readStorefrontData, requireArray, requireBoolean, requireNumber, requireRecord, requireString, requireStringFromKeys, requireUnknownRecord, resolveAccountView, resolveBadgeForeground, resolveCartBoundsHeals, resolveCategorySelection, resolveCheckoutFields, resolveDeliveryPromise, resolveDisplayStock, resolveHideStockCounter, resolveLicenseTerm, resolveMenuLinksForSlot, resolvePayWhatYouWantMinimum, resolveProductVideoEmbedSrc, resolveQuantityBounds, resolveSupportChannels, resolveUnsellableLineIds, resolveVariantStock, reviewsForProduct, roundCurrency, sanitizeMerchantHtml, sortCatalogCards, startCartMutation, stripMerchantHtmlImages, submitContactTicket, toShopReviews, toStarCount, useCart, useNavigationLinks, useOnlineUserCount, usePagedShopReviews, useShopReviews, useStorefront, validateCheckoutFieldValue, validateCheckoutFields, validateContactSubmission, withRequiredAddons };
|
package/dist/index.js
CHANGED
|
@@ -1473,8 +1473,12 @@ function resolvePriceLabel(product) {
|
|
|
1473
1473
|
}
|
|
1474
1474
|
return formatMoney(product.price, product.currency);
|
|
1475
1475
|
}
|
|
1476
|
+
function isCardSoldOut(product) {
|
|
1477
|
+
if (isProductSoldOut(product)) return true;
|
|
1478
|
+
return product.priceVariants.length > 0 ? product.priceVariants.every((variant) => isSelectionSoldOut(product, variant)) : isSelectionSoldOut(product, null);
|
|
1479
|
+
}
|
|
1476
1480
|
function buildProductCard(product, settings, sortPriority) {
|
|
1477
|
-
const soldOut =
|
|
1481
|
+
const soldOut = isCardSoldOut(product);
|
|
1478
1482
|
const isInfoCard = product.productType === "INFO_CARD";
|
|
1479
1483
|
const stock = resolveDisplayStock(product);
|
|
1480
1484
|
const hideCounter = resolveHideStockCounter(product, settings);
|
|
@@ -2538,7 +2542,7 @@ function useNavigationLinks(slot, themeLinks, authored) {
|
|
|
2538
2542
|
}
|
|
2539
2543
|
|
|
2540
2544
|
// src/reviews.ts
|
|
2541
|
-
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
2545
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
2542
2546
|
var SHOP_REVIEW_PAGE_SIZE = 12;
|
|
2543
2547
|
function toTimestamp(value) {
|
|
2544
2548
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -2578,7 +2582,8 @@ function toShopReviews(rows, labels) {
|
|
|
2578
2582
|
dateLabel: formatDateLabel(timestamp),
|
|
2579
2583
|
timestamp,
|
|
2580
2584
|
productTitle: row.product_title?.trim() || null,
|
|
2581
|
-
verified: row.verified === true
|
|
2585
|
+
verified: row.verified === true,
|
|
2586
|
+
automated: row.is_automated === true
|
|
2582
2587
|
};
|
|
2583
2588
|
}).sort((a, b) => b.timestamp - a.timestamp);
|
|
2584
2589
|
}
|
|
@@ -2587,20 +2592,83 @@ function reviewsForProduct(reviews, productTitle) {
|
|
|
2587
2592
|
if (!title) return [];
|
|
2588
2593
|
return reviews.filter((review) => review.productTitle === title);
|
|
2589
2594
|
}
|
|
2590
|
-
async function
|
|
2595
|
+
async function loadShopReviewsPage(options) {
|
|
2596
|
+
const product = options.product?.trim() || null;
|
|
2597
|
+
const result = await getShoppex().getShopReviewsPage(options.cursor ?? null, product ? { product } : void 0);
|
|
2598
|
+
if (!result.success || !result.data) {
|
|
2599
|
+
throw new Error(result.message?.trim() || "Reviews could not be loaded.");
|
|
2600
|
+
}
|
|
2601
|
+
if (product !== null && result.data.product !== product) {
|
|
2602
|
+
throw new Error("This store does not filter reviews by product yet.");
|
|
2603
|
+
}
|
|
2604
|
+
const { pagination } = result.data;
|
|
2605
|
+
return {
|
|
2606
|
+
reviews: toShopReviews(result.data.feedback, options.labels),
|
|
2607
|
+
nextCursor: pagination.has_more ? pagination.next_cursor : null,
|
|
2608
|
+
summary: result.data.summary ?? null
|
|
2609
|
+
};
|
|
2610
|
+
}
|
|
2611
|
+
async function loadLatestWrittenReviews(limit, labels, options = {}) {
|
|
2591
2612
|
const written = [];
|
|
2592
2613
|
const seen = /* @__PURE__ */ new Set();
|
|
2593
2614
|
let cursor = null;
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2615
|
+
try {
|
|
2616
|
+
while (written.length < limit) {
|
|
2617
|
+
const page = await loadShopReviewsPage({ cursor, product: options.product, labels: { anonymousAuthor: labels.anonymousAuthor, emptyComment: "" } });
|
|
2618
|
+
written.push(...page.reviews.filter((review) => !review.automated && review.comment !== ""));
|
|
2619
|
+
if (!page.nextCursor || seen.has(page.nextCursor)) break;
|
|
2620
|
+
seen.add(page.nextCursor);
|
|
2621
|
+
cursor = page.nextCursor;
|
|
2622
|
+
}
|
|
2623
|
+
} catch {
|
|
2624
|
+
return null;
|
|
2602
2625
|
}
|
|
2603
|
-
return
|
|
2626
|
+
return written.slice(0, limit).map((review) => ({ ...review, comment: review.comment || labels.emptyComment }));
|
|
2627
|
+
}
|
|
2628
|
+
function usePagedShopReviews(options) {
|
|
2629
|
+
const product = options.product?.trim() || null;
|
|
2630
|
+
const { anonymousAuthor, emptyComment } = options.labels;
|
|
2631
|
+
const [state, setState] = useState3({ status: "loading" });
|
|
2632
|
+
const [cursor, setCursor] = useState3(null);
|
|
2633
|
+
const generation = useRef2(0);
|
|
2634
|
+
useEffect3(() => {
|
|
2635
|
+
const current = generation.current += 1;
|
|
2636
|
+
setState({ status: "loading" });
|
|
2637
|
+
setCursor(null);
|
|
2638
|
+
loadShopReviewsPage({ product, labels: { anonymousAuthor, emptyComment } }).then((page) => {
|
|
2639
|
+
if (generation.current !== current) return;
|
|
2640
|
+
setCursor(page.nextCursor);
|
|
2641
|
+
setState({
|
|
2642
|
+
status: "ready",
|
|
2643
|
+
reviews: page.reviews,
|
|
2644
|
+
summary: page.summary,
|
|
2645
|
+
hasMore: page.nextCursor !== null,
|
|
2646
|
+
loadingMore: false,
|
|
2647
|
+
moreFailed: false
|
|
2648
|
+
});
|
|
2649
|
+
}).catch(() => {
|
|
2650
|
+
if (generation.current === current) setState({ status: "error" });
|
|
2651
|
+
});
|
|
2652
|
+
}, [product, anonymousAuthor, emptyComment]);
|
|
2653
|
+
const loadMore = useCallback2(() => {
|
|
2654
|
+
if (state.status !== "ready" || state.loadingMore || cursor === null) return;
|
|
2655
|
+
const current = generation.current;
|
|
2656
|
+
setState({ ...state, loadingMore: true, moreFailed: false });
|
|
2657
|
+
loadShopReviewsPage({ cursor, product, labels: { anonymousAuthor, emptyComment } }).then((page) => {
|
|
2658
|
+
if (generation.current !== current) return;
|
|
2659
|
+
setCursor(page.nextCursor);
|
|
2660
|
+
setState((previous) => previous.status !== "ready" ? previous : {
|
|
2661
|
+
...previous,
|
|
2662
|
+
reviews: [...previous.reviews, ...page.reviews],
|
|
2663
|
+
hasMore: page.nextCursor !== null,
|
|
2664
|
+
loadingMore: false
|
|
2665
|
+
});
|
|
2666
|
+
}).catch(() => {
|
|
2667
|
+
if (generation.current !== current) return;
|
|
2668
|
+
setState((previous) => previous.status !== "ready" ? previous : { ...previous, loadingMore: false, moreFailed: true });
|
|
2669
|
+
});
|
|
2670
|
+
}, [state, cursor, product, anonymousAuthor, emptyComment]);
|
|
2671
|
+
return { ...state, loadMore };
|
|
2604
2672
|
}
|
|
2605
2673
|
function averageRating(reviews) {
|
|
2606
2674
|
if (reviews.length === 0) return null;
|
|
@@ -2659,15 +2727,19 @@ async function buildShopPageModel(page) {
|
|
|
2659
2727
|
};
|
|
2660
2728
|
}
|
|
2661
2729
|
async function loadShopPage(slug) {
|
|
2730
|
+
let result;
|
|
2731
|
+
try {
|
|
2732
|
+
result = await getShoppex().getPage(slug);
|
|
2733
|
+
} catch {
|
|
2734
|
+
return { status: "error" };
|
|
2735
|
+
}
|
|
2736
|
+
if (!result.success) return result.status === 404 ? { status: "missing" } : { status: "error" };
|
|
2737
|
+
const page = result.data;
|
|
2738
|
+
if (!page || typeof page.name !== "string" || !page.name.trim()) return { status: "missing" };
|
|
2662
2739
|
try {
|
|
2663
|
-
const result = await getShoppex().getPage(slug);
|
|
2664
|
-
const page = result.success ? result.data : void 0;
|
|
2665
|
-
if (!page || typeof page.name !== "string" || !page.name.trim()) {
|
|
2666
|
-
return { status: "missing" };
|
|
2667
|
-
}
|
|
2668
2740
|
return { status: "ready", page: await buildShopPageModel(page) };
|
|
2669
2741
|
} catch {
|
|
2670
|
-
return { status: "
|
|
2742
|
+
return { status: "error" };
|
|
2671
2743
|
}
|
|
2672
2744
|
}
|
|
2673
2745
|
|
|
@@ -2769,6 +2841,7 @@ export {
|
|
|
2769
2841
|
hasInjectedStorefrontData,
|
|
2770
2842
|
isAccountTab,
|
|
2771
2843
|
isBlankMerchantHtml,
|
|
2844
|
+
isCardSoldOut,
|
|
2772
2845
|
isCheckboxValueChecked,
|
|
2773
2846
|
isImplementedAccountTab,
|
|
2774
2847
|
isProductSoldOut,
|
|
@@ -2776,6 +2849,7 @@ export {
|
|
|
2776
2849
|
isSelectionSoldOut,
|
|
2777
2850
|
loadLatestWrittenReviews,
|
|
2778
2851
|
loadShopPage,
|
|
2852
|
+
loadShopReviewsPage,
|
|
2779
2853
|
missingRequiredCheckoutValues,
|
|
2780
2854
|
optionalBoolean,
|
|
2781
2855
|
optionalString,
|
|
@@ -2824,6 +2898,7 @@ export {
|
|
|
2824
2898
|
useCart,
|
|
2825
2899
|
useNavigationLinks,
|
|
2826
2900
|
useOnlineUserCount,
|
|
2901
|
+
usePagedShopReviews,
|
|
2827
2902
|
useShopReviews,
|
|
2828
2903
|
useStorefront,
|
|
2829
2904
|
validateCheckoutFieldValue,
|