@replohq/sdk 2.12.0 → 2.13.1

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.
@@ -1,7 +1,7 @@
1
1
  export const BUILD_METADATA = {
2
2
  "packageName": "@replohq/sdk",
3
- "version": "2.12.0",
3
+ "version": "2.13.1",
4
4
  "branch": "HEAD",
5
- "commit": "3979195a451aa6e4c83a6eb0e1ec8eff5b2f8b81",
6
- "builtAt": "2026-10-29T23:04:10.969Z"
5
+ "commit": "a6aec8a72961f223f309de6a13ed271ccfddcb62",
6
+ "builtAt": "2026-10-30T19:41:38.224Z"
7
7
  };
@@ -8,10 +8,16 @@ type JudgemeReviewsData = z.infer<typeof judgemeProductReviewsLoaderOutputSchema
8
8
  type JudgemeReviewsLoaderProps = {
9
9
  loaderKey: LoaderKeyProp<LoaderKey>;
10
10
  productId: string;
11
- perPage?: number;
12
- page?: number;
13
11
  children: (data: JudgemeReviewsData) => ReactNode;
14
12
  fallback?: ReactNode;
15
- };
16
- export declare function JudgemeReviewsLoader({ loaderKey, productId, perPage, page, children, fallback, }: JudgemeReviewsLoaderProps): import("react/jsx-runtime").JSX.Element;
13
+ } & ({
14
+ perPage?: number;
15
+ page?: number;
16
+ reviewIds?: never;
17
+ } | {
18
+ reviewIds: readonly string[];
19
+ perPage?: never;
20
+ page?: never;
21
+ });
22
+ export declare function JudgemeReviewsLoader({ loaderKey, productId, perPage, page, reviewIds, children, fallback, }: JudgemeReviewsLoaderProps): import("react/jsx-runtime").JSX.Element;
17
23
  export {};
@@ -7,12 +7,14 @@ import { LoaderErrorBoundary } from "./loader-error-boundary";
7
7
  function buildReviewsArgs({
8
8
  productId,
9
9
  perPage,
10
- page
10
+ page,
11
+ reviewIds
11
12
  }) {
12
13
  return {
13
14
  productId,
14
15
  ...perPage !== void 0 ? { perPage } : {},
15
- ...page !== void 0 ? { page } : {}
16
+ ...page !== void 0 ? { page } : {},
17
+ ...reviewIds !== void 0 ? { reviewIds: [...reviewIds] } : {}
16
18
  };
17
19
  }
18
20
  function JudgemeReviewsLoaderInner({
@@ -20,9 +22,10 @@ function JudgemeReviewsLoaderInner({
20
22
  productId,
21
23
  perPage,
22
24
  page,
25
+ reviewIds,
23
26
  children
24
27
  }) {
25
- const args = buildReviewsArgs({ productId, perPage, page });
28
+ const args = buildReviewsArgs({ productId, perPage, page, reviewIds });
26
29
  const { data } = useSuspenseQuery({
27
30
  queryKey: [loaderKey, args],
28
31
  queryFn: () => {
@@ -36,6 +39,7 @@ function JudgemeReviewsLoader({
36
39
  productId,
37
40
  perPage,
38
41
  page,
42
+ reviewIds,
39
43
  children,
40
44
  fallback
41
45
  }) {
@@ -43,7 +47,7 @@ function JudgemeReviewsLoader({
43
47
  LoaderErrorBoundary,
44
48
  {
45
49
  fallback: fallback ?? null,
46
- resetKey: `${loaderKey}:${productId}:${perPage ?? ""}:${page ?? ""}`,
50
+ resetKey: `${loaderKey}:${productId}:${perPage ?? ""}:${page ?? ""}:${reviewIds?.join(",") ?? ""}`,
47
51
  children: /* @__PURE__ */ jsx(Suspense, { fallback: fallback ?? null, children: /* @__PURE__ */ jsx(
48
52
  JudgemeReviewsLoaderInner,
49
53
  {
@@ -51,6 +55,7 @@ function JudgemeReviewsLoader({
51
55
  productId,
52
56
  perPage,
53
57
  page,
58
+ reviewIds,
54
59
  children
55
60
  }
56
61
  ) })
@@ -966,6 +966,7 @@ export declare const judgemeReviewLoaderItemSchema: z.ZodObject<{
966
966
  createdAt: z.ZodNullable<z.ZodString>;
967
967
  verifiedBuyer: z.ZodBoolean;
968
968
  reviewerName: z.ZodNullable<z.ZodString>;
969
+ pinned: z.ZodBoolean;
969
970
  }, z.core.$strip>;
970
971
  export declare const judgemeProductReviewsLoaderOutputSchema: z.ZodObject<{
971
972
  reviews: z.ZodArray<z.ZodObject<{
@@ -976,6 +977,7 @@ export declare const judgemeProductReviewsLoaderOutputSchema: z.ZodObject<{
976
977
  createdAt: z.ZodNullable<z.ZodString>;
977
978
  verifiedBuyer: z.ZodBoolean;
978
979
  reviewerName: z.ZodNullable<z.ZodString>;
980
+ pinned: z.ZodBoolean;
979
981
  }, z.core.$strip>>;
980
982
  }, z.core.$strip>;
981
983
  export declare const judgemeProductReviewAggregateLoaderOutputSchema: z.ZodObject<{
@@ -318,7 +318,8 @@ const judgemeReviewLoaderItemSchema = z.object({
318
318
  score: z.number().nullable(),
319
319
  createdAt: z.string().nullable(),
320
320
  verifiedBuyer: z.boolean(),
321
- reviewerName: z.string().nullable()
321
+ reviewerName: z.string().nullable(),
322
+ pinned: z.boolean()
322
323
  });
323
324
  const judgemeProductReviewsLoaderOutputSchema = z.object({
324
325
  reviews: z.array(judgemeReviewLoaderItemSchema)
@@ -1,62 +1,87 @@
1
+ import { exhaustiveSwitch } from "../_vendor/replo-utils/lib/misc.mjs";
1
2
  const REPLO_IMAGE_CDN = "https://assets.replocdn.com";
2
3
  function isContentfulImagesCdn(hostname) {
3
4
  return /^images(?:\.[a-z]+)?\.ctfassets\.net$/i.test(hostname);
4
5
  }
5
- function isPassthroughSource(src) {
6
+ const MAX_PARSED_SOURCES = 1e3;
7
+ const parsedSources = /* @__PURE__ */ new Map();
8
+ function parseSource(src) {
9
+ const isAbsolute = /^https:\/\//i.test(src);
10
+ let url;
6
11
  try {
7
- return /\.(avif|svg)$/i.test(new URL(src, REPLO_IMAGE_CDN).pathname);
12
+ url = new URL(src, REPLO_IMAGE_CDN);
8
13
  } catch {
9
- return false;
14
+ url = null;
10
15
  }
11
- }
12
- function contentfulImagesApiUrl({
13
- src,
14
- width,
15
- quality
16
- }) {
17
- const url = new URL(src);
18
- url.searchParams.set("w", String(width));
19
- url.searchParams.set("q", String(quality ?? 75));
20
- if (!url.searchParams.has("fm")) {
21
- url.searchParams.set("fm", "webp");
16
+ if (url !== null && /\.(avif|svg)$/i.test(url.pathname)) {
17
+ return { kind: "unchanged" };
18
+ }
19
+ if (!isAbsolute) {
20
+ return { kind: "relative" };
22
21
  }
23
- return url.toString();
22
+ if (url === null) {
23
+ return { kind: "unchanged" };
24
+ }
25
+ if (/(^|\.)ctfassets\.net$/i.test(url.hostname)) {
26
+ if (!isContentfulImagesCdn(url.hostname)) {
27
+ return { kind: "unchanged" };
28
+ }
29
+ const [, hrefBeforeSearch = "", , hash = ""] = /^([^?#]*)(\?[^#]*)?(#.*)?$/.exec(url.href) ?? [];
30
+ return {
31
+ kind: "contentfulImagesApi",
32
+ hrefBeforeSearch,
33
+ searchParams: url.searchParams,
34
+ hash
35
+ };
36
+ }
37
+ if (/(^|\.)replocdn\.com$/i.test(url.hostname)) {
38
+ return { kind: "replocdn" };
39
+ }
40
+ return {
41
+ kind: "external",
42
+ passthroughUrl: `${REPLO_IMAGE_CDN}/images/external?url=${encodeURIComponent(src)}`
43
+ };
24
44
  }
25
45
  function cloudflareLoader({
26
46
  src,
27
47
  width,
28
48
  quality
29
49
  }) {
30
- if (isPassthroughSource(src)) {
31
- return src;
50
+ let source = parsedSources.get(src);
51
+ if (!source) {
52
+ if (parsedSources.size >= MAX_PARSED_SOURCES) {
53
+ parsedSources.clear();
54
+ }
55
+ source = parseSource(src);
56
+ parsedSources.set(src, source);
32
57
  }
33
58
  const isDevelopment = process.env.NODE_ENV === "development";
34
- const params = [`width=${width}`, `quality=${quality ?? 75}`, "format=auto"];
35
- if (/^https:\/\//i.test(src)) {
36
- let hostname;
37
- try {
38
- hostname = new URL(src).hostname;
39
- } catch {
40
- return src;
41
- }
42
- if (/(^|\.)ctfassets\.net$/i.test(hostname)) {
43
- if (isContentfulImagesCdn(hostname)) {
44
- return contentfulImagesApiUrl({ src, width, quality });
59
+ const params = `width=${width},quality=${quality ?? 75},format=auto`;
60
+ return exhaustiveSwitch(
61
+ source,
62
+ "kind"
63
+ )({
64
+ unchanged: src,
65
+ contentfulImagesApi: (contentfulSource) => {
66
+ const searchParams = new URLSearchParams(contentfulSource.searchParams);
67
+ searchParams.set("w", String(width));
68
+ searchParams.set("q", String(quality ?? 75));
69
+ if (!searchParams.has("fm")) {
70
+ searchParams.set("fm", "webp");
45
71
  }
46
- return src;
47
- }
48
- if (/(^|\.)replocdn\.com$/i.test(hostname)) {
72
+ return `${contentfulSource.hrefBeforeSearch}?${searchParams.toString()}${contentfulSource.hash}`;
73
+ },
74
+ replocdn: () => {
49
75
  const resizerOrigin = isDevelopment ? REPLO_IMAGE_CDN : "";
50
- return `${resizerOrigin}/cdn-cgi/image/${params.join(",")}/${src}`;
76
+ return `${resizerOrigin}/cdn-cgi/image/${params}/${src}`;
77
+ },
78
+ external: (externalSource) => {
79
+ return `${REPLO_IMAGE_CDN}/cdn-cgi/image/${params},onerror=redirect/${externalSource.passthroughUrl}`;
80
+ },
81
+ relative: () => {
82
+ return isDevelopment ? src : `/cdn-cgi/image/${params}/${src.startsWith("/") ? src.slice(1) : src}`;
51
83
  }
52
- const passthroughUrl = `${REPLO_IMAGE_CDN}/images/external?url=${encodeURIComponent(src)}`;
53
- return `${REPLO_IMAGE_CDN}/cdn-cgi/image/${[...params, "onerror=redirect"].join(",")}/${passthroughUrl}`;
54
- }
55
- if (isDevelopment) {
56
- return src;
57
- }
58
- const normalizedSrc = src.startsWith("/") ? src.slice(1) : src;
59
- return `/cdn-cgi/image/${params.join(",")}/${normalizedSrc}`;
84
+ });
60
85
  }
61
86
  export {
62
87
  cloudflareLoader as default
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sdk",
3
- "version": "2.12.0",
3
+ "version": "2.13.1",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sdk",
6
- "version": "2.12.0",
6
+ "version": "2.13.1",
7
7
  "branch": "HEAD",
8
- "commit": "3979195a451aa6e4c83a6eb0e1ec8eff5b2f8b81",
9
- "builtAt": "2026-10-29T23:04:10.969Z"
8
+ "commit": "a6aec8a72961f223f309de6a13ed271ccfddcb62",
9
+ "builtAt": "2026-10-30T19:41:38.224Z"
10
10
  },
11
11
  "description": "Replo SDK — cart, analytics, and data loaders for agent-built Next.js sites.",
12
12
  "license": "SEE LICENSE IN LICENSE",