@cimplify/sdk 0.48.1 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react.d.mts +96 -3
- package/dist/react.d.ts +96 -3
- package/dist/react.js +304 -4
- package/dist/react.mjs +302 -5
- package/dist/server.d.mts +28 -1
- package/dist/server.d.ts +28 -1
- package/dist/server.js +125 -0
- package/dist/server.mjs +116 -1
- package/package.json +1 -1
- package/registry/date-slot-picker.json +1 -1
- package/registry/index.json +24 -0
- package/registry/media-gallery.json +16 -0
- package/registry/product-model-3d.json +13 -0
- package/registry/slot-picker.json +1 -1
- package/registry/store-video.json +13 -0
package/dist/react.mjs
CHANGED
|
@@ -6232,6 +6232,8 @@ function SlotPicker({
|
|
|
6232
6232
|
schedulingMode = "intraday",
|
|
6233
6233
|
durationUnit,
|
|
6234
6234
|
durationValue,
|
|
6235
|
+
hideElapsedSlots = true,
|
|
6236
|
+
minLeadMinutes = 0,
|
|
6235
6237
|
emptyMessage = "No available slots",
|
|
6236
6238
|
className,
|
|
6237
6239
|
classNames
|
|
@@ -6245,7 +6247,15 @@ function SlotPicker({
|
|
|
6245
6247
|
enabled: slotsProp === void 0 && !!serviceId && !!date
|
|
6246
6248
|
}
|
|
6247
6249
|
);
|
|
6248
|
-
const
|
|
6250
|
+
const rawSlots = slotsProp ?? fetched;
|
|
6251
|
+
const slots = useMemo(() => {
|
|
6252
|
+
if (!hideElapsedSlots) return rawSlots;
|
|
6253
|
+
const cutoff = Date.now() + minLeadMinutes * 6e4;
|
|
6254
|
+
return rawSlots.filter((slot) => {
|
|
6255
|
+
const start = Date.parse(slot.start_time);
|
|
6256
|
+
return Number.isNaN(start) || start >= cutoff;
|
|
6257
|
+
});
|
|
6258
|
+
}, [rawSlots, hideElapsedSlots, minLeadMinutes]);
|
|
6249
6259
|
if (isLoading && slots.length === 0) {
|
|
6250
6260
|
return /* @__PURE__ */ jsx(
|
|
6251
6261
|
"div",
|
|
@@ -6371,6 +6381,8 @@ function DateSlotPicker({
|
|
|
6371
6381
|
schedulingMode,
|
|
6372
6382
|
durationUnit,
|
|
6373
6383
|
durationValue,
|
|
6384
|
+
hideElapsedSlots = true,
|
|
6385
|
+
minLeadMinutes = 0,
|
|
6374
6386
|
className,
|
|
6375
6387
|
classNames
|
|
6376
6388
|
}) {
|
|
@@ -6516,7 +6528,9 @@ function DateSlotPicker({
|
|
|
6516
6528
|
showPrice,
|
|
6517
6529
|
schedulingMode,
|
|
6518
6530
|
durationUnit,
|
|
6519
|
-
durationValue
|
|
6531
|
+
durationValue,
|
|
6532
|
+
hideElapsedSlots,
|
|
6533
|
+
minLeadMinutes
|
|
6520
6534
|
}
|
|
6521
6535
|
) })
|
|
6522
6536
|
]
|
|
@@ -6961,6 +6975,289 @@ function ProductImageGallery({
|
|
|
6961
6975
|
)
|
|
6962
6976
|
] });
|
|
6963
6977
|
}
|
|
6978
|
+
var ASPECT_STYLES2 = {
|
|
6979
|
+
square: { aspectRatio: "1/1" },
|
|
6980
|
+
"4/3": { aspectRatio: "4/3" },
|
|
6981
|
+
"16/9": { aspectRatio: "16/9" },
|
|
6982
|
+
"16/10": { aspectRatio: "16/10" },
|
|
6983
|
+
"3/4": { aspectRatio: "3/4" }
|
|
6984
|
+
};
|
|
6985
|
+
function StoreVideo({
|
|
6986
|
+
src,
|
|
6987
|
+
poster,
|
|
6988
|
+
alt,
|
|
6989
|
+
aspectRatio = "16/9",
|
|
6990
|
+
controls = false,
|
|
6991
|
+
autoplay = true,
|
|
6992
|
+
loop = true,
|
|
6993
|
+
muted = true,
|
|
6994
|
+
lazy = true,
|
|
6995
|
+
className
|
|
6996
|
+
}) {
|
|
6997
|
+
const ref = useRef(null);
|
|
6998
|
+
const [inView, setInView] = useState(!lazy);
|
|
6999
|
+
useEffect(() => {
|
|
7000
|
+
if (!lazy || inView) return;
|
|
7001
|
+
const node = ref.current;
|
|
7002
|
+
if (!node || typeof IntersectionObserver === "undefined") {
|
|
7003
|
+
setInView(true);
|
|
7004
|
+
return;
|
|
7005
|
+
}
|
|
7006
|
+
const observer = new IntersectionObserver(
|
|
7007
|
+
(entries) => {
|
|
7008
|
+
if (entries.some((e) => e.isIntersecting)) {
|
|
7009
|
+
setInView(true);
|
|
7010
|
+
observer.disconnect();
|
|
7011
|
+
}
|
|
7012
|
+
},
|
|
7013
|
+
{ rootMargin: "200px" }
|
|
7014
|
+
);
|
|
7015
|
+
observer.observe(node);
|
|
7016
|
+
return () => observer.disconnect();
|
|
7017
|
+
}, [lazy, inView]);
|
|
7018
|
+
return /* @__PURE__ */ jsx(
|
|
7019
|
+
"div",
|
|
7020
|
+
{
|
|
7021
|
+
"data-cimplify-store-video": true,
|
|
7022
|
+
className,
|
|
7023
|
+
style: { position: "relative", overflow: "hidden", ...ASPECT_STYLES2[aspectRatio] },
|
|
7024
|
+
children: /* @__PURE__ */ jsx(
|
|
7025
|
+
"video",
|
|
7026
|
+
{
|
|
7027
|
+
ref,
|
|
7028
|
+
src: inView ? src : void 0,
|
|
7029
|
+
poster,
|
|
7030
|
+
autoPlay: autoplay,
|
|
7031
|
+
loop,
|
|
7032
|
+
muted,
|
|
7033
|
+
playsInline: true,
|
|
7034
|
+
controls,
|
|
7035
|
+
preload: lazy ? "metadata" : "auto",
|
|
7036
|
+
"aria-label": alt,
|
|
7037
|
+
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" },
|
|
7038
|
+
children: poster ? /* @__PURE__ */ jsx(
|
|
7039
|
+
"img",
|
|
7040
|
+
{
|
|
7041
|
+
src: poster,
|
|
7042
|
+
alt: alt ?? "",
|
|
7043
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
7044
|
+
}
|
|
7045
|
+
) : null
|
|
7046
|
+
}
|
|
7047
|
+
)
|
|
7048
|
+
}
|
|
7049
|
+
);
|
|
7050
|
+
}
|
|
7051
|
+
var ASPECT_STYLES3 = {
|
|
7052
|
+
square: { aspectRatio: "1/1" },
|
|
7053
|
+
"4/3": { aspectRatio: "4/3" },
|
|
7054
|
+
"16/9": { aspectRatio: "16/9" },
|
|
7055
|
+
"3/4": { aspectRatio: "3/4" }
|
|
7056
|
+
};
|
|
7057
|
+
var MODEL_VIEWER_CDN = "https://unpkg.com/@google/model-viewer@4.0.0/dist/model-viewer.min.js";
|
|
7058
|
+
var modelViewerLoadPromise = null;
|
|
7059
|
+
function ensureModelViewer() {
|
|
7060
|
+
if (typeof window === "undefined") return Promise.resolve();
|
|
7061
|
+
if (modelViewerLoadPromise) return modelViewerLoadPromise;
|
|
7062
|
+
if (window.customElements?.get("model-viewer")) {
|
|
7063
|
+
modelViewerLoadPromise = Promise.resolve();
|
|
7064
|
+
return modelViewerLoadPromise;
|
|
7065
|
+
}
|
|
7066
|
+
modelViewerLoadPromise = new Promise((resolve, reject) => {
|
|
7067
|
+
const script = document.createElement("script");
|
|
7068
|
+
script.type = "module";
|
|
7069
|
+
script.src = MODEL_VIEWER_CDN;
|
|
7070
|
+
script.onload = () => resolve();
|
|
7071
|
+
script.onerror = () => reject(new Error("Failed to load model-viewer"));
|
|
7072
|
+
document.head.appendChild(script);
|
|
7073
|
+
});
|
|
7074
|
+
return modelViewerLoadPromise;
|
|
7075
|
+
}
|
|
7076
|
+
function ProductModel3D({
|
|
7077
|
+
src,
|
|
7078
|
+
iosSrc,
|
|
7079
|
+
poster,
|
|
7080
|
+
alt,
|
|
7081
|
+
aspectRatio = "square",
|
|
7082
|
+
ar = true,
|
|
7083
|
+
autoRotate = true,
|
|
7084
|
+
cameraControls = true,
|
|
7085
|
+
className
|
|
7086
|
+
}) {
|
|
7087
|
+
const [ready, setReady] = useState(false);
|
|
7088
|
+
useEffect(() => {
|
|
7089
|
+
let cancelled = false;
|
|
7090
|
+
ensureModelViewer().then(
|
|
7091
|
+
() => {
|
|
7092
|
+
if (!cancelled) setReady(true);
|
|
7093
|
+
},
|
|
7094
|
+
() => {
|
|
7095
|
+
}
|
|
7096
|
+
);
|
|
7097
|
+
return () => {
|
|
7098
|
+
cancelled = true;
|
|
7099
|
+
};
|
|
7100
|
+
}, []);
|
|
7101
|
+
return /* @__PURE__ */ jsx(
|
|
7102
|
+
"div",
|
|
7103
|
+
{
|
|
7104
|
+
"data-cimplify-product-model-3d": true,
|
|
7105
|
+
className,
|
|
7106
|
+
style: { position: "relative", overflow: "hidden", ...ASPECT_STYLES3[aspectRatio] },
|
|
7107
|
+
children: ready ? React10.createElement("model-viewer", {
|
|
7108
|
+
src,
|
|
7109
|
+
"ios-src": iosSrc,
|
|
7110
|
+
alt,
|
|
7111
|
+
poster,
|
|
7112
|
+
ar: ar || void 0,
|
|
7113
|
+
"ar-modes": ar ? "webxr scene-viewer quick-look" : void 0,
|
|
7114
|
+
"camera-controls": cameraControls || void 0,
|
|
7115
|
+
"auto-rotate": autoRotate || void 0,
|
|
7116
|
+
"shadow-intensity": "1",
|
|
7117
|
+
style: { width: "100%", height: "100%", backgroundColor: "transparent" }
|
|
7118
|
+
}) : poster ? React10.createElement("img", {
|
|
7119
|
+
src: poster,
|
|
7120
|
+
alt: alt ?? "",
|
|
7121
|
+
"data-cimplify-product-model-3d-loading": true,
|
|
7122
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
7123
|
+
}) : React10.createElement("div", {
|
|
7124
|
+
"data-cimplify-product-model-3d-loading": true,
|
|
7125
|
+
style: { width: "100%", height: "100%", backgroundColor: "var(--muted, #f3f4f6)" }
|
|
7126
|
+
})
|
|
7127
|
+
}
|
|
7128
|
+
);
|
|
7129
|
+
}
|
|
7130
|
+
var ASPECT_STYLES4 = {
|
|
7131
|
+
square: { aspectRatio: "1/1" },
|
|
7132
|
+
"4/3": { aspectRatio: "4/3" },
|
|
7133
|
+
"16/10": { aspectRatio: "16/10" },
|
|
7134
|
+
"3/4": { aspectRatio: "3/4" }
|
|
7135
|
+
};
|
|
7136
|
+
function thumbnailFor(item) {
|
|
7137
|
+
if (item.type === "image") return item.src;
|
|
7138
|
+
return item.poster ?? null;
|
|
7139
|
+
}
|
|
7140
|
+
function thumbIcon(item) {
|
|
7141
|
+
if (item.type === "video") return "\u25B6";
|
|
7142
|
+
if (item.type === "model") return "\u25C6";
|
|
7143
|
+
return null;
|
|
7144
|
+
}
|
|
7145
|
+
function MediaGallery({
|
|
7146
|
+
items,
|
|
7147
|
+
productName,
|
|
7148
|
+
aspectRatio = "4/3",
|
|
7149
|
+
className
|
|
7150
|
+
}) {
|
|
7151
|
+
const validItems = useMemo(
|
|
7152
|
+
() => items.filter((i) => typeof i.src === "string" && i.src.trim().length > 0),
|
|
7153
|
+
[items]
|
|
7154
|
+
);
|
|
7155
|
+
const [selected, setSelected] = useState(0);
|
|
7156
|
+
useEffect(() => {
|
|
7157
|
+
setSelected(0);
|
|
7158
|
+
}, [validItems.length, productName]);
|
|
7159
|
+
if (validItems.length === 0) return null;
|
|
7160
|
+
const active = validItems[selected] ?? validItems[0];
|
|
7161
|
+
return /* @__PURE__ */ jsxs("div", { "data-cimplify-media-gallery": true, className, children: [
|
|
7162
|
+
/* @__PURE__ */ jsx(
|
|
7163
|
+
"div",
|
|
7164
|
+
{
|
|
7165
|
+
"data-cimplify-media-gallery-main": true,
|
|
7166
|
+
style: { position: "relative", overflow: "hidden", ...ASPECT_STYLES4[aspectRatio] },
|
|
7167
|
+
children: active.type === "image" ? /* @__PURE__ */ jsx(
|
|
7168
|
+
"img",
|
|
7169
|
+
{
|
|
7170
|
+
src: active.src,
|
|
7171
|
+
alt: active.alt ?? productName,
|
|
7172
|
+
style: { width: "100%", height: "100%", objectFit: "cover" },
|
|
7173
|
+
"data-cimplify-media-gallery-active": true
|
|
7174
|
+
}
|
|
7175
|
+
) : active.type === "video" ? /* @__PURE__ */ jsx(
|
|
7176
|
+
StoreVideo,
|
|
7177
|
+
{
|
|
7178
|
+
src: active.src,
|
|
7179
|
+
poster: active.poster,
|
|
7180
|
+
alt: active.alt ?? productName,
|
|
7181
|
+
aspectRatio: "square",
|
|
7182
|
+
lazy: false
|
|
7183
|
+
}
|
|
7184
|
+
) : /* @__PURE__ */ jsx(
|
|
7185
|
+
ProductModel3D,
|
|
7186
|
+
{
|
|
7187
|
+
src: active.src,
|
|
7188
|
+
iosSrc: active.iosSrc,
|
|
7189
|
+
poster: active.poster,
|
|
7190
|
+
alt: active.alt ?? productName,
|
|
7191
|
+
aspectRatio: "square"
|
|
7192
|
+
}
|
|
7193
|
+
)
|
|
7194
|
+
}
|
|
7195
|
+
),
|
|
7196
|
+
validItems.length > 1 && /* @__PURE__ */ jsx(
|
|
7197
|
+
RadioGroup,
|
|
7198
|
+
{
|
|
7199
|
+
"aria-label": `${productName} media thumbnails`,
|
|
7200
|
+
value: String(selected),
|
|
7201
|
+
onValueChange: (v) => setSelected(Number(v)),
|
|
7202
|
+
"data-cimplify-media-gallery-thumbnails": true,
|
|
7203
|
+
style: { display: "flex", gap: "0.5rem", marginTop: "0.75rem" },
|
|
7204
|
+
children: validItems.map((item, index) => {
|
|
7205
|
+
const thumb = thumbnailFor(item);
|
|
7206
|
+
const icon = thumbIcon(item);
|
|
7207
|
+
const isSelected = selected === index;
|
|
7208
|
+
return /* @__PURE__ */ jsxs(
|
|
7209
|
+
Radio.Root,
|
|
7210
|
+
{
|
|
7211
|
+
value: String(index),
|
|
7212
|
+
"data-cimplify-media-gallery-thumb": true,
|
|
7213
|
+
"data-selected": isSelected || void 0,
|
|
7214
|
+
"data-type": item.type,
|
|
7215
|
+
style: {
|
|
7216
|
+
position: "relative",
|
|
7217
|
+
width: "4rem",
|
|
7218
|
+
height: "4rem",
|
|
7219
|
+
overflow: "hidden",
|
|
7220
|
+
padding: 0,
|
|
7221
|
+
border: "none",
|
|
7222
|
+
cursor: "pointer",
|
|
7223
|
+
backgroundColor: "var(--muted, #f3f4f6)"
|
|
7224
|
+
},
|
|
7225
|
+
children: [
|
|
7226
|
+
thumb ? /* @__PURE__ */ jsx(
|
|
7227
|
+
"img",
|
|
7228
|
+
{
|
|
7229
|
+
src: thumb,
|
|
7230
|
+
alt: "",
|
|
7231
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
7232
|
+
}
|
|
7233
|
+
) : null,
|
|
7234
|
+
icon ? /* @__PURE__ */ jsx(
|
|
7235
|
+
"span",
|
|
7236
|
+
{
|
|
7237
|
+
"aria-hidden": true,
|
|
7238
|
+
style: {
|
|
7239
|
+
position: "absolute",
|
|
7240
|
+
inset: 0,
|
|
7241
|
+
display: "flex",
|
|
7242
|
+
alignItems: "center",
|
|
7243
|
+
justifyContent: "center",
|
|
7244
|
+
color: "white",
|
|
7245
|
+
fontSize: "0.875rem",
|
|
7246
|
+
textShadow: "0 1px 2px rgba(0,0,0,0.6)",
|
|
7247
|
+
pointerEvents: "none"
|
|
7248
|
+
},
|
|
7249
|
+
children: icon
|
|
7250
|
+
}
|
|
7251
|
+
) : null
|
|
7252
|
+
]
|
|
7253
|
+
},
|
|
7254
|
+
`${item.src}-${index}`
|
|
7255
|
+
);
|
|
7256
|
+
})
|
|
7257
|
+
}
|
|
7258
|
+
)
|
|
7259
|
+
] });
|
|
7260
|
+
}
|
|
6964
7261
|
function CartLineItemRow({
|
|
6965
7262
|
item,
|
|
6966
7263
|
onRemove,
|
|
@@ -8367,7 +8664,7 @@ var CardVariant = /* @__PURE__ */ ((CardVariant2) => {
|
|
|
8367
8664
|
CardVariant2["Subscription"] = "subscription";
|
|
8368
8665
|
return CardVariant2;
|
|
8369
8666
|
})(CardVariant || {});
|
|
8370
|
-
var
|
|
8667
|
+
var ASPECT_STYLES5 = {
|
|
8371
8668
|
square: { aspectRatio: "1/1" },
|
|
8372
8669
|
"4/3": { aspectRatio: "4/3" },
|
|
8373
8670
|
"16/10": { aspectRatio: "16/10" },
|
|
@@ -8476,7 +8773,7 @@ function ProductCard({
|
|
|
8476
8773
|
{
|
|
8477
8774
|
"data-cimplify-product-card-image-container": true,
|
|
8478
8775
|
className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
|
|
8479
|
-
style:
|
|
8776
|
+
style: ASPECT_STYLES5[aspectRatio],
|
|
8480
8777
|
children: renderImage ? renderImage({ src: imageUrl, alt: product.name, className: classNames?.image }) : /* @__PURE__ */ jsx(
|
|
8481
8778
|
"img",
|
|
8482
8779
|
{
|
|
@@ -13601,4 +13898,4 @@ function SparkleIcon({ className }) {
|
|
|
13601
13898
|
);
|
|
13602
13899
|
}
|
|
13603
13900
|
|
|
13604
|
-
export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatWidget, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, CustomerInputFields, DatePicker, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TimePicker, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|
|
13901
|
+
export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatWidget, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, CustomerInputFields, DatePicker, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MediaGallery, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductModel3D, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, StoreVideo, SubscriptionCard, TagPills, TimePicker, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|
package/dist/server.d.mts
CHANGED
|
@@ -68,7 +68,18 @@ declare const tags: {
|
|
|
68
68
|
readonly collection: (id: string) => string;
|
|
69
69
|
readonly collectionProducts: (id: string) => string;
|
|
70
70
|
readonly business: () => string;
|
|
71
|
+
readonly brand: () => string;
|
|
71
72
|
readonly locations: () => string;
|
|
73
|
+
readonly location: (id: string) => string;
|
|
74
|
+
readonly locale: () => string;
|
|
75
|
+
readonly pricing: () => string;
|
|
76
|
+
readonly tag: (name: string) => string;
|
|
77
|
+
readonly addons: () => string;
|
|
78
|
+
readonly addon: (id: string) => string;
|
|
79
|
+
readonly subscriptions: () => string;
|
|
80
|
+
readonly subscription: (id: string) => string;
|
|
81
|
+
readonly stock: () => string;
|
|
82
|
+
readonly stockFor: (productId: string) => string;
|
|
72
83
|
readonly orders: (customerId: string) => string;
|
|
73
84
|
readonly order: (id: string) => string;
|
|
74
85
|
};
|
|
@@ -89,10 +100,26 @@ declare function revalidateCategory(id: string): Promise<void>;
|
|
|
89
100
|
declare function revalidateCollections(): Promise<void>;
|
|
90
101
|
declare function revalidateCollection(id: string): Promise<void>;
|
|
91
102
|
declare function revalidateBusiness(): Promise<void>;
|
|
103
|
+
declare function revalidateBrand(): Promise<void>;
|
|
104
|
+
declare function revalidateLocations(): Promise<void>;
|
|
105
|
+
declare function revalidateLocation(id: string): Promise<void>;
|
|
106
|
+
declare function revalidatePricing(): Promise<void>;
|
|
107
|
+
declare function revalidateAddOns(): Promise<void>;
|
|
108
|
+
declare function revalidateAddOn(id: string): Promise<void>;
|
|
109
|
+
declare function revalidateSubscriptions(): Promise<void>;
|
|
110
|
+
declare function revalidateSubscription(id: string): Promise<void>;
|
|
111
|
+
declare function revalidateStock(productId?: string): Promise<void>;
|
|
92
112
|
/**
|
|
93
113
|
* Escape hatch: invalidate by raw tag string. Prefer the typed helpers
|
|
94
114
|
* above where possible — they keep the tag scheme in one place.
|
|
95
115
|
*/
|
|
96
116
|
declare function revalidateByTag(tag: string): Promise<void>;
|
|
97
117
|
|
|
98
|
-
|
|
118
|
+
interface RevalidateRouteOptions {
|
|
119
|
+
secret?: string;
|
|
120
|
+
revalidateTag?: (tag: string) => void;
|
|
121
|
+
now?: () => number;
|
|
122
|
+
}
|
|
123
|
+
declare function revalidateRouteHandler(req: Request, options?: RevalidateRouteOptions): Promise<Response>;
|
|
124
|
+
|
|
125
|
+
export { CimplifyClient, type RevalidateRouteOptions, type ServerClientOptions, getServerClient, revalidateAddOn, revalidateAddOns, revalidateBrand, revalidateBusiness, revalidateByTag, revalidateCategories, revalidateCategory, revalidateCollection, revalidateCollections, revalidateLocation, revalidateLocations, revalidatePricing, revalidateProduct, revalidateProducts, revalidateRouteHandler, revalidateStock, revalidateSubscription, revalidateSubscriptions, tags };
|
package/dist/server.d.ts
CHANGED
|
@@ -68,7 +68,18 @@ declare const tags: {
|
|
|
68
68
|
readonly collection: (id: string) => string;
|
|
69
69
|
readonly collectionProducts: (id: string) => string;
|
|
70
70
|
readonly business: () => string;
|
|
71
|
+
readonly brand: () => string;
|
|
71
72
|
readonly locations: () => string;
|
|
73
|
+
readonly location: (id: string) => string;
|
|
74
|
+
readonly locale: () => string;
|
|
75
|
+
readonly pricing: () => string;
|
|
76
|
+
readonly tag: (name: string) => string;
|
|
77
|
+
readonly addons: () => string;
|
|
78
|
+
readonly addon: (id: string) => string;
|
|
79
|
+
readonly subscriptions: () => string;
|
|
80
|
+
readonly subscription: (id: string) => string;
|
|
81
|
+
readonly stock: () => string;
|
|
82
|
+
readonly stockFor: (productId: string) => string;
|
|
72
83
|
readonly orders: (customerId: string) => string;
|
|
73
84
|
readonly order: (id: string) => string;
|
|
74
85
|
};
|
|
@@ -89,10 +100,26 @@ declare function revalidateCategory(id: string): Promise<void>;
|
|
|
89
100
|
declare function revalidateCollections(): Promise<void>;
|
|
90
101
|
declare function revalidateCollection(id: string): Promise<void>;
|
|
91
102
|
declare function revalidateBusiness(): Promise<void>;
|
|
103
|
+
declare function revalidateBrand(): Promise<void>;
|
|
104
|
+
declare function revalidateLocations(): Promise<void>;
|
|
105
|
+
declare function revalidateLocation(id: string): Promise<void>;
|
|
106
|
+
declare function revalidatePricing(): Promise<void>;
|
|
107
|
+
declare function revalidateAddOns(): Promise<void>;
|
|
108
|
+
declare function revalidateAddOn(id: string): Promise<void>;
|
|
109
|
+
declare function revalidateSubscriptions(): Promise<void>;
|
|
110
|
+
declare function revalidateSubscription(id: string): Promise<void>;
|
|
111
|
+
declare function revalidateStock(productId?: string): Promise<void>;
|
|
92
112
|
/**
|
|
93
113
|
* Escape hatch: invalidate by raw tag string. Prefer the typed helpers
|
|
94
114
|
* above where possible — they keep the tag scheme in one place.
|
|
95
115
|
*/
|
|
96
116
|
declare function revalidateByTag(tag: string): Promise<void>;
|
|
97
117
|
|
|
98
|
-
|
|
118
|
+
interface RevalidateRouteOptions {
|
|
119
|
+
secret?: string;
|
|
120
|
+
revalidateTag?: (tag: string) => void;
|
|
121
|
+
now?: () => number;
|
|
122
|
+
}
|
|
123
|
+
declare function revalidateRouteHandler(req: Request, options?: RevalidateRouteOptions): Promise<Response>;
|
|
124
|
+
|
|
125
|
+
export { CimplifyClient, type RevalidateRouteOptions, type ServerClientOptions, getServerClient, revalidateAddOn, revalidateAddOns, revalidateBrand, revalidateBusiness, revalidateByTag, revalidateCategories, revalidateCategory, revalidateCollection, revalidateCollections, revalidateLocation, revalidateLocations, revalidatePricing, revalidateProduct, revalidateProducts, revalidateRouteHandler, revalidateStock, revalidateSubscription, revalidateSubscriptions, tags };
|
package/dist/server.js
CHANGED
|
@@ -41,7 +41,19 @@ var tags = {
|
|
|
41
41
|
collection: (id) => `cimplify:collection:${id}`,
|
|
42
42
|
collectionProducts: (id) => `cimplify:collection:${id}:products`,
|
|
43
43
|
business: () => "cimplify:business",
|
|
44
|
+
brand: () => "cimplify:brand",
|
|
44
45
|
locations: () => "cimplify:locations",
|
|
46
|
+
location: (id) => `cimplify:location:${id}`,
|
|
47
|
+
locale: () => "cimplify:locale",
|
|
48
|
+
pricing: () => "cimplify:pricing",
|
|
49
|
+
// Product-level tag (e.g. "vegan", "bestseller"), not "cache tag".
|
|
50
|
+
tag: (name) => `cimplify:tag:${name}`,
|
|
51
|
+
addons: () => "cimplify:addons",
|
|
52
|
+
addon: (id) => `cimplify:addon:${id}`,
|
|
53
|
+
subscriptions: () => "cimplify:subscriptions",
|
|
54
|
+
subscription: (id) => `cimplify:subscription:${id}`,
|
|
55
|
+
stock: () => "cimplify:stock",
|
|
56
|
+
stockFor: (productId) => `cimplify:stock:${productId}`,
|
|
45
57
|
orders: (customerId) => `cimplify:orders:${customerId}`,
|
|
46
58
|
order: (id) => `cimplify:order:${id}`
|
|
47
59
|
};
|
|
@@ -88,21 +100,134 @@ async function revalidateCollection(id) {
|
|
|
88
100
|
async function revalidateBusiness() {
|
|
89
101
|
return revalidate(tags.business());
|
|
90
102
|
}
|
|
103
|
+
async function revalidateBrand() {
|
|
104
|
+
return revalidate(tags.brand());
|
|
105
|
+
}
|
|
106
|
+
async function revalidateLocations() {
|
|
107
|
+
return revalidate(tags.locations());
|
|
108
|
+
}
|
|
109
|
+
async function revalidateLocation(id) {
|
|
110
|
+
return revalidate(tags.location(id), tags.locations());
|
|
111
|
+
}
|
|
112
|
+
async function revalidatePricing() {
|
|
113
|
+
return revalidate(tags.pricing(), tags.products());
|
|
114
|
+
}
|
|
115
|
+
async function revalidateAddOns() {
|
|
116
|
+
return revalidate(tags.addons());
|
|
117
|
+
}
|
|
118
|
+
async function revalidateAddOn(id) {
|
|
119
|
+
return revalidate(tags.addon(id), tags.addons());
|
|
120
|
+
}
|
|
121
|
+
async function revalidateSubscriptions() {
|
|
122
|
+
return revalidate(tags.subscriptions());
|
|
123
|
+
}
|
|
124
|
+
async function revalidateSubscription(id) {
|
|
125
|
+
return revalidate(tags.subscription(id), tags.subscriptions());
|
|
126
|
+
}
|
|
127
|
+
async function revalidateStock(productId) {
|
|
128
|
+
return productId ? revalidate(tags.stockFor(productId), tags.stock()) : revalidate(tags.stock());
|
|
129
|
+
}
|
|
91
130
|
async function revalidateByTag(tag) {
|
|
92
131
|
return revalidate(tag);
|
|
93
132
|
}
|
|
94
133
|
|
|
134
|
+
// src/server/revalidate-route.ts
|
|
135
|
+
var TIMESTAMP_HEADER = "x-cimplify-timestamp";
|
|
136
|
+
var SIGNATURE_HEADER = "x-cimplify-signature";
|
|
137
|
+
var SIGNATURE_PREFIX = "sha256=";
|
|
138
|
+
var MAX_SKEW_MS = 5 * 60 * 1e3;
|
|
139
|
+
var SECRET_ENV = "CIMPLIFY_REVALIDATE_SECRET";
|
|
140
|
+
async function revalidateRouteHandler(req, options = {}) {
|
|
141
|
+
const secret = options.secret ?? envSecret();
|
|
142
|
+
if (!secret) return text(`revalidate disabled: ${SECRET_ENV} not set`, 500);
|
|
143
|
+
const timestamp = req.headers.get(TIMESTAMP_HEADER);
|
|
144
|
+
const signature = req.headers.get(SIGNATURE_HEADER);
|
|
145
|
+
if (!timestamp || !signature) return text("missing auth headers", 401);
|
|
146
|
+
const ts = Number.parseInt(timestamp, 10);
|
|
147
|
+
const now = options.now ?? Date.now;
|
|
148
|
+
if (!Number.isFinite(ts) || Math.abs(now() - ts) > MAX_SKEW_MS) {
|
|
149
|
+
return text("stale or invalid timestamp", 401);
|
|
150
|
+
}
|
|
151
|
+
const body = await req.text();
|
|
152
|
+
if (!await verifyHmac(secret, `${timestamp}.${body}`, signature)) {
|
|
153
|
+
return text("invalid signature", 401);
|
|
154
|
+
}
|
|
155
|
+
let parsed;
|
|
156
|
+
try {
|
|
157
|
+
parsed = JSON.parse(body);
|
|
158
|
+
} catch {
|
|
159
|
+
return text("invalid json", 400);
|
|
160
|
+
}
|
|
161
|
+
const tags2 = Array.isArray(parsed.tags) ? parsed.tags.filter((t) => typeof t === "string" && t.length > 0) : [];
|
|
162
|
+
if (tags2.length === 0) return text("no tags", 400);
|
|
163
|
+
const revalidate2 = options.revalidateTag ?? await loadRevalidateTag();
|
|
164
|
+
for (const tag of tags2) revalidate2(tag);
|
|
165
|
+
return Response.json({ ok: true, revalidated: tags2.length });
|
|
166
|
+
}
|
|
167
|
+
var cachedRevalidateTag = null;
|
|
168
|
+
async function loadRevalidateTag() {
|
|
169
|
+
if (cachedRevalidateTag) return cachedRevalidateTag;
|
|
170
|
+
const specifier = "next/cache";
|
|
171
|
+
const mod = await import(
|
|
172
|
+
/* webpackIgnore: true */
|
|
173
|
+
/* @vite-ignore */
|
|
174
|
+
specifier
|
|
175
|
+
);
|
|
176
|
+
cachedRevalidateTag = mod.revalidateTag;
|
|
177
|
+
return cachedRevalidateTag;
|
|
178
|
+
}
|
|
179
|
+
async function verifyHmac(secret, payload, signatureHeader) {
|
|
180
|
+
if (!signatureHeader.startsWith(SIGNATURE_PREFIX)) return false;
|
|
181
|
+
const providedBytes = hexToBytes(signatureHeader.slice(SIGNATURE_PREFIX.length));
|
|
182
|
+
if (!providedBytes) return false;
|
|
183
|
+
const enc = new TextEncoder();
|
|
184
|
+
const key = await crypto.subtle.importKey(
|
|
185
|
+
"raw",
|
|
186
|
+
enc.encode(secret),
|
|
187
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
188
|
+
false,
|
|
189
|
+
["verify"]
|
|
190
|
+
);
|
|
191
|
+
return crypto.subtle.verify("HMAC", key, providedBytes, enc.encode(payload));
|
|
192
|
+
}
|
|
193
|
+
function hexToBytes(hex) {
|
|
194
|
+
if (hex.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(hex)) return null;
|
|
195
|
+
const buf = new ArrayBuffer(hex.length / 2);
|
|
196
|
+
const out = new Uint8Array(buf);
|
|
197
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
198
|
+
out[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
function envSecret() {
|
|
203
|
+
const proc = globalThis.process;
|
|
204
|
+
return proc?.env?.[SECRET_ENV];
|
|
205
|
+
}
|
|
206
|
+
function text(message, status) {
|
|
207
|
+
return new Response(message, { status, headers: { "content-type": "text/plain" } });
|
|
208
|
+
}
|
|
209
|
+
|
|
95
210
|
Object.defineProperty(exports, "CimplifyError", {
|
|
96
211
|
enumerable: true,
|
|
97
212
|
get: function () { return chunkTKOTACKZ_js.CimplifyError; }
|
|
98
213
|
});
|
|
99
214
|
exports.getServerClient = getServerClient;
|
|
215
|
+
exports.revalidateAddOn = revalidateAddOn;
|
|
216
|
+
exports.revalidateAddOns = revalidateAddOns;
|
|
217
|
+
exports.revalidateBrand = revalidateBrand;
|
|
100
218
|
exports.revalidateBusiness = revalidateBusiness;
|
|
101
219
|
exports.revalidateByTag = revalidateByTag;
|
|
102
220
|
exports.revalidateCategories = revalidateCategories;
|
|
103
221
|
exports.revalidateCategory = revalidateCategory;
|
|
104
222
|
exports.revalidateCollection = revalidateCollection;
|
|
105
223
|
exports.revalidateCollections = revalidateCollections;
|
|
224
|
+
exports.revalidateLocation = revalidateLocation;
|
|
225
|
+
exports.revalidateLocations = revalidateLocations;
|
|
226
|
+
exports.revalidatePricing = revalidatePricing;
|
|
106
227
|
exports.revalidateProduct = revalidateProduct;
|
|
107
228
|
exports.revalidateProducts = revalidateProducts;
|
|
229
|
+
exports.revalidateRouteHandler = revalidateRouteHandler;
|
|
230
|
+
exports.revalidateStock = revalidateStock;
|
|
231
|
+
exports.revalidateSubscription = revalidateSubscription;
|
|
232
|
+
exports.revalidateSubscriptions = revalidateSubscriptions;
|
|
108
233
|
exports.tags = tags;
|