@tokenoftrust/storefront-runner 2.5.5 → 2.5.6

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.
@@ -18,8 +18,25 @@ import type { CatalogImage } from "@tot/public-runtime";
18
18
  import { placeholderDataUri, isUsableImageUrl } from "@/lib/content/shared/placeholder";
19
19
  import { resolveImage } from "@/lib/assets/shared/imageAttrs";
20
20
 
21
+ export type PublicGalleryImage = Pick<CatalogImage,
22
+ "id" | "url" | "alt" | "position" | "width" | "height" | "variant_ids" | "rehosted">;
23
+
24
+ /** Project before Astro serializes props; private provenance stays in the catalog. */
25
+ export function publicGalleryImages(images: readonly CatalogImage[]): PublicGalleryImage[] {
26
+ return images.map((image) => ({
27
+ id: image.id,
28
+ url: image.url,
29
+ position: image.position,
30
+ ...(image.alt !== undefined ? { alt: image.alt } : {}),
31
+ ...(image.width !== undefined ? { width: image.width } : {}),
32
+ ...(image.height !== undefined ? { height: image.height } : {}),
33
+ ...(image.variant_ids !== undefined ? { variant_ids: [...image.variant_ids] } : {}),
34
+ ...(image.rehosted !== undefined ? { rehosted: image.rehosted } : {}),
35
+ }));
36
+ }
37
+
21
38
  interface Props {
22
- images: CatalogImage[];
39
+ images: PublicGalleryImage[];
23
40
  title: string;
24
41
  productHandle: string;
25
42
  activeImageId?: string;
@@ -36,7 +53,7 @@ const isShopifyCdnUrl = (url: string): boolean =>
36
53
  * decision (same as <Img> on the PLP) so rehosted images use the same
37
54
  * provider-neutral shared-CDN URL on Cloudflare and CloudFront.
38
55
  */
39
- function mainImage(img: CatalogImage, title: string): { src: string; srcset?: string } {
56
+ function mainImage(img: PublicGalleryImage, title: string): { src: string; srcset?: string } {
40
57
  return resolveImage({
41
58
  src: img.url,
42
59
  rehosted: img.rehosted,
@@ -53,7 +70,7 @@ function mainImage(img: CatalogImage, title: string): { src: string; srcset?: st
53
70
  * URLs draw a deterministic placeholder.
54
71
  */
55
72
  const THUMB_WIDTH = 160;
56
- function thumbSrc(img: CatalogImage, title: string): string {
73
+ function thumbSrc(img: PublicGalleryImage, title: string): string {
57
74
  if (!isUsableImageUrl(img.url, img.rehosted)) {
58
75
  return placeholderDataUri({
59
76
  seed: img.id || title,
@@ -718,8 +718,10 @@ export class PublishedContentProvider implements ContentProvider {
718
718
  return page ?? ((await this.usesVersionedContent()) ? null : this.base.getPage(slug));
719
719
  }
720
720
  async listPages(): Promise<EditorialPage[]> {
721
+ // Editorial enumeration follows its source, not the generic artifact fallback.
722
+ if (!(await this.usesVersionedContent())) return this.base.listPages();
721
723
  const paths = await this.listArtifactPaths("pages/");
722
- if (paths === null) return this.base.listPages();
724
+ if (paths === null) return [];
723
725
  const pages = await Promise.all(
724
726
  paths
725
727
  .filter((path) => path.endsWith(".json"))
@@ -728,8 +730,10 @@ export class PublishedContentProvider implements ContentProvider {
728
730
  return pages.filter((page): page is EditorialPage => page !== null);
729
731
  }
730
732
 
731
- readArtifact(relative: string): Promise<string | null> {
732
- return this.publishedRaw(relative);
733
+ async readArtifact(relative: string): Promise<string | null> {
734
+ const raw = await this.publishedRaw(relative);
735
+ if (raw !== null) return raw;
736
+ return (await this.usesVersionedContent()) ? null : this.base.readArtifact(relative);
733
737
  }
734
738
 
735
739
  async derivedArtifact(name: string): Promise<DerivedArtifact | null> {
@@ -743,8 +747,9 @@ export class PublishedContentProvider implements ContentProvider {
743
747
  async listArtifactPaths(prefix = ""): Promise<string[] | null> {
744
748
  const root = contentArtifactPath(this.tenantId, "");
745
749
  const paths = await this.versionedPaths();
746
- return paths?.filter((path) => path.startsWith(`${root}${prefix}`))
747
- .map((path) => path.slice(root.length)) ?? null;
750
+ if (paths === null) return this.base.listArtifactPaths(prefix);
751
+ return paths.filter((path) => path.startsWith(`${root}${prefix}`))
752
+ .map((path) => path.slice(root.length));
748
753
  }
749
754
  }
750
755
 
@@ -11,7 +11,7 @@ import { homeCrumbLabel, siteTrail } from "@/lib/content/shared/breadcrumbs";
11
11
  import Badge from "@/components/content/storefront/Badge.astro";
12
12
  import ProductCard from "@/components/catalog/storefront/ProductCard.astro";
13
13
  import Section from "@/components/content/storefront/Section.astro";
14
- import ImageGallery from "@/components/catalog/storefront/islands/ImageGallery.tsx";
14
+ import ImageGallery, { publicGalleryImages } from "@/components/catalog/storefront/islands/ImageGallery.tsx";
15
15
  import VariantSelector, { publicSelectorVariants } from "@/components/catalog/storefront/islands/VariantSelector.tsx";
16
16
  import CheckoutComplianceGate from "@/components/compliance/storefront/islands/CheckoutComplianceGate.tsx";
17
17
  import RecentlyViewed from "@/components/catalog/storefront/islands/RecentlyViewed.tsx";
@@ -345,7 +345,7 @@ const structuredData = {
345
345
  <div>
346
346
  <ImageGallery
347
347
  client:idle
348
- images={product.images}
348
+ images={publicGalleryImages(product.images)}
349
349
  title={product.title}
350
350
  productHandle={product.handle}
351
351
  />
@@ -420,7 +420,12 @@ const structuredData = {
420
420
  productTitle={product.title}
421
421
  checkoutCart={checkoutCart}
422
422
  pricing={pricing}
423
- handoffUrl={sampleHandoff ? undefined : cartApiPath}
423
+ handoffUrl={
424
+ !sampleHandoff &&
425
+ (Astro.locals.browserEnvironment.environment === "live" || Astro.locals.browserEnvironment.environment === "local")
426
+ ? cartApiPath
427
+ : undefined
428
+ }
424
429
  />
425
430
  {/* Regulated-tenant checkout ENFORCEMENT gate. Intercepts the
426
431
  managed-cart handoff to clear age + ship-to compliance server-side
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/storefront-runner",
3
- "version": "2.5.5",
3
+ "version": "2.5.6",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
6
6
  "packageManager": "pnpm@11.9.0",