@standhigher/besttrack-page-extension 0.5.6 → 0.5.8
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 +4 -2
- package/dist/index.js +9 -3
- package/dist/validation.js +1 -1
- package/package.json +2 -2
- package/dist/{chunk-KD7KFFFK.js → chunk-KEW42Y26.js} +28 -28
package/README.md
CHANGED
|
@@ -67,6 +67,8 @@ Query results and watermark state are transient.
|
|
|
67
67
|
|
|
68
68
|
Document props and bindings must remain JSON-only and must not contain a token,
|
|
69
69
|
secret, customer order data, email address, or live query result. Merchant
|
|
70
|
-
resources use stable Shopify IDs
|
|
71
|
-
|
|
70
|
+
resources use stable Shopify IDs. Catalog display prices may be stored on
|
|
71
|
+
product snapshots as `{ amount, currencyCode }` minor units; formatted price
|
|
72
|
+
strings, live availability, tokens, and secrets stay out of PageDocument.
|
|
73
|
+
Production URLs must be public HTTPS URLs. Missing display data and
|
|
72
74
|
unsafe resource URLs render controlled fallbacks.
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
isValidTrackingNumber,
|
|
12
12
|
resolveShopifyResources,
|
|
13
13
|
safeTrackingPageUrl
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-KEW42Y26.js";
|
|
15
15
|
|
|
16
16
|
// src/ready-to-go.tsx
|
|
17
17
|
import { createContext, useCallback as useCallback2, useContext, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
@@ -1054,6 +1054,10 @@ function PackageContents({ items }) {
|
|
|
1054
1054
|
] }, item.id);
|
|
1055
1055
|
}) });
|
|
1056
1056
|
}
|
|
1057
|
+
function formatTrackPageRecommendPrice(price) {
|
|
1058
|
+
if (!price || !Number.isInteger(price.amount)) return "";
|
|
1059
|
+
return `$ ${(price.amount / 100).toFixed(2)}`;
|
|
1060
|
+
}
|
|
1057
1061
|
function RecommendationCards({ items }) {
|
|
1058
1062
|
const autoplay = useMemo(() => Autoplay({ delay: 3e3, stopOnInteraction: false, stopOnMouseEnter: true }), []);
|
|
1059
1063
|
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, align: "start", slidesToScroll: 1 }, [autoplay]);
|
|
@@ -1107,11 +1111,12 @@ function RecommendationCards({ items }) {
|
|
|
1107
1111
|
!hideButtons && canScrollPrev ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Previous", onClick: () => emblaApi?.scrollPrev(), style: { ...buttonStyle, left: -40 }, children: arrow("15 18 9 12 15 6") }) : null,
|
|
1108
1112
|
/* @__PURE__ */ jsx("div", { ref: emblaRef, style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: { display: "flex" }, children: items.map((item) => {
|
|
1109
1113
|
const href = safeHref(item.href);
|
|
1114
|
+
const displayPrice = formatTrackPageRecommendPrice(item.price);
|
|
1110
1115
|
const card = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1111
1116
|
/* @__PURE__ */ jsx("div", { style: { width: 262, height: 262, maxWidth: "100%", borderRadius: 8, border: "1px solid #E3E3E3", overflow: "hidden", background: "#f1f5f9" }, children: /* @__PURE__ */ jsx(ProductImage, { src: item.imageUrl, alt: item.title, size: 262 }) }),
|
|
1112
1117
|
/* @__PURE__ */ jsxs("div", { style: { padding: "12px 8px", textAlign: "center", fontSize: 14 }, children: [
|
|
1113
1118
|
/* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#334155" }, children: item.title }),
|
|
1114
|
-
|
|
1119
|
+
displayPrice ? /* @__PURE__ */ jsx("p", { style: { margin: "4px 0 0", fontWeight: 600, color: "#0f172a" }, children: displayPrice }) : null,
|
|
1115
1120
|
item.description ? /* @__PURE__ */ jsx("p", { style: { margin: "4px 0 0", color: "#64748b", fontSize: 13 }, children: item.description }) : null
|
|
1116
1121
|
] })
|
|
1117
1122
|
] });
|
|
@@ -1528,7 +1533,8 @@ function configuredRecommendations(products) {
|
|
|
1528
1533
|
title: product.title || product.id,
|
|
1529
1534
|
description: "",
|
|
1530
1535
|
imageUrl: product.imageUrl,
|
|
1531
|
-
href: product.handle ? `/products/${product.handle}` : void 0
|
|
1536
|
+
href: product.handle ? `/products/${product.handle}` : void 0,
|
|
1537
|
+
...product.price ? { price: product.price } : {}
|
|
1532
1538
|
}));
|
|
1533
1539
|
}
|
|
1534
1540
|
function ReadyToGoRecommendationsEditor(block) {
|
package/dist/validation.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standhigher/besttrack-page-extension",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
4
4
|
"description": "BestTrack business extension entry point for @standhigher/puck-page-builder.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"embla-carousel-autoplay": "^8.6.0",
|
|
24
24
|
"embla-carousel-react": "^8.6.0",
|
|
25
|
-
"@standhigher/puck-page-builder": "0.12.
|
|
25
|
+
"@standhigher/puck-page-builder": "0.12.8"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.5.1",
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
// src/tracking-page-url.ts
|
|
2
|
+
function hasControlCharacter(value) {
|
|
3
|
+
return [...value].some((character) => character.charCodeAt(0) < 32);
|
|
4
|
+
}
|
|
5
|
+
function isLocalDevelopmentHost(hostname) {
|
|
6
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
7
|
+
}
|
|
8
|
+
function allowsLocalhostByDefault() {
|
|
9
|
+
return typeof window !== "undefined" && isLocalDevelopmentHost(window.location.hostname);
|
|
10
|
+
}
|
|
11
|
+
function safeTrackingPageUrl(value, options = {}) {
|
|
12
|
+
if (typeof value !== "string" || !value || value.trim() !== value || hasControlCharacter(value)) return void 0;
|
|
13
|
+
try {
|
|
14
|
+
const url = new URL(value);
|
|
15
|
+
if (url.username || url.password) return void 0;
|
|
16
|
+
if (url.protocol === "https:" && !isLocalDevelopmentHost(url.hostname)) return url.toString();
|
|
17
|
+
if (url.protocol === "http:" && isLocalDevelopmentHost(url.hostname) && (options.allowLocalhost ?? allowsLocalhostByDefault())) return url.toString();
|
|
18
|
+
return void 0;
|
|
19
|
+
} catch {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function isSafeTrackingPageUrl(value, options) {
|
|
24
|
+
return safeTrackingPageUrl(value, options) !== void 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
// src/tracking-page-runtime.ts
|
|
2
28
|
function isValidTrackingNumber(value) {
|
|
3
29
|
return /^[A-Za-z0-9_-]{6,64}$/.test(value);
|
|
@@ -27,32 +53,6 @@ function formatTrackingPageMoney(value, locale = "en-US") {
|
|
|
27
53
|
}
|
|
28
54
|
}
|
|
29
55
|
|
|
30
|
-
// src/tracking-page-url.ts
|
|
31
|
-
function hasControlCharacter(value) {
|
|
32
|
-
return [...value].some((character) => character.charCodeAt(0) < 32);
|
|
33
|
-
}
|
|
34
|
-
function isLocalDevelopmentHost(hostname) {
|
|
35
|
-
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
36
|
-
}
|
|
37
|
-
function allowsLocalhostByDefault() {
|
|
38
|
-
return typeof window !== "undefined" && isLocalDevelopmentHost(window.location.hostname);
|
|
39
|
-
}
|
|
40
|
-
function safeTrackingPageUrl(value, options = {}) {
|
|
41
|
-
if (typeof value !== "string" || !value || value.trim() !== value || hasControlCharacter(value)) return void 0;
|
|
42
|
-
try {
|
|
43
|
-
const url = new URL(value);
|
|
44
|
-
if (url.username || url.password) return void 0;
|
|
45
|
-
if (url.protocol === "https:" && !isLocalDevelopmentHost(url.hostname)) return url.toString();
|
|
46
|
-
if (url.protocol === "http:" && isLocalDevelopmentHost(url.hostname) && (options.allowLocalhost ?? allowsLocalhostByDefault())) return url.toString();
|
|
47
|
-
return void 0;
|
|
48
|
-
} catch {
|
|
49
|
-
return void 0;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function isSafeTrackingPageUrl(value, options) {
|
|
53
|
-
return safeTrackingPageUrl(value, options) !== void 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
56
|
// src/shopify-resource-contract.ts
|
|
57
57
|
var resourcePattern = /^gid:\/\/shopify\/(Product|Collection)\/[1-9]\d*$/;
|
|
58
58
|
function isShopifyResourceReference(value, kind) {
|
|
@@ -112,14 +112,14 @@ function getShopifyResourceResolutionError(reference, resolution) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
export {
|
|
115
|
+
safeTrackingPageUrl,
|
|
116
|
+
isSafeTrackingPageUrl,
|
|
115
117
|
isValidTrackingNumber,
|
|
116
118
|
isValidOrderNumber,
|
|
117
119
|
isValidOrderEmail,
|
|
118
120
|
isEmptyTrackingPageResult,
|
|
119
121
|
isTrackingPageResourceReference,
|
|
120
122
|
formatTrackingPageMoney,
|
|
121
|
-
safeTrackingPageUrl,
|
|
122
|
-
isSafeTrackingPageUrl,
|
|
123
123
|
isShopifyResourceReference,
|
|
124
124
|
resolveShopifyResources,
|
|
125
125
|
getResolvedShopifyResource,
|