@replohq/sdk 1.5.0 → 1.6.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.
Files changed (43) hide show
  1. package/_vendor/replo-utils/lib/url.d.ts +5 -1
  2. package/cart/cart-actions.js +2 -1
  3. package/cart/cart-actions.js.map +2 -2
  4. package/cart/cart-provider.d.ts +15 -3
  5. package/cart/cart-provider.js +49 -6
  6. package/cart/cart-provider.js.map +2 -2
  7. package/cart/cart-types.d.ts +15 -0
  8. package/cart/cart-types.js.map +1 -1
  9. package/cart/gateways/cart-gateway.d.ts +7 -0
  10. package/cart/gateways/cart-gateway.js.map +2 -2
  11. package/cart/gateways/cookie-cart-gateway.d.ts +9 -0
  12. package/cart/gateways/cookie-cart-gateway.js +54 -3
  13. package/cart/gateways/cookie-cart-gateway.js.map +2 -2
  14. package/cart/gateways/resolver-cart-gateway.js +4 -0
  15. package/cart/gateways/resolver-cart-gateway.js.map +2 -2
  16. package/cart/gateways/stripe-cart-gateway.d.ts +14 -0
  17. package/cart/gateways/stripe-cart-gateway.js +6 -1
  18. package/cart/gateways/stripe-cart-gateway.js.map +2 -2
  19. package/cart/hooks/use-add-to-cart.d.ts +3 -1
  20. package/cart/hooks/use-add-to-cart.js +1 -1
  21. package/cart/hooks/use-add-to-cart.js.map +2 -2
  22. package/cart/utils/cart-adjustments.d.ts +29 -0
  23. package/cart/utils/cart-adjustments.js +81 -0
  24. package/cart/utils/cart-adjustments.js.map +7 -0
  25. package/cart/utils/cart-utils.d.ts +14 -0
  26. package/cart/utils/cart-utils.js +43 -0
  27. package/cart/utils/cart-utils.js.map +2 -2
  28. package/cart/utils/cookie-cart-persistence.d.ts +4 -2
  29. package/cart/utils/cookie-cart-persistence.js +35 -21
  30. package/cart/utils/cookie-cart-persistence.js.map +3 -3
  31. package/gateways/canopy-api.d.ts +25 -0
  32. package/gateways/canopy-api.js +40 -0
  33. package/gateways/canopy-api.js.map +2 -2
  34. package/lib/buildMetadata.js +3 -3
  35. package/loaders/loader-schemas.d.ts +5 -0
  36. package/loaders/loader-schemas.js +2 -0
  37. package/loaders/loader-schemas.js.map +2 -2
  38. package/loaders/rebuy-recommendations-loader.d.ts +1 -0
  39. package/next/config.d.ts +18 -0
  40. package/next/config.js.map +2 -2
  41. package/package.json +4 -4
  42. package/providers/replo-provider.d.ts +19 -0
  43. package/providers/replo-provider.js.map +2 -2
@@ -1,4 +1,5 @@
1
1
  import type { Cart } from "../cart/cart-schema";
2
+ import { z } from "zod";
2
3
  import { CanopyError } from "../lib/canopy-error";
3
4
  type CanopyApiGatewayErrorConfig = {
4
5
  message: string;
@@ -10,6 +11,18 @@ export declare class CanopyApiGatewayError extends CanopyError {
10
11
  statusCode: number;
11
12
  constructor(config: CanopyApiGatewayErrorConfig);
12
13
  }
14
+ declare const reconciledCartLineSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
15
+ variantId: z.ZodString;
16
+ status: z.ZodLiteral<"purchasable">;
17
+ unitPriceMinor: z.ZodNumber;
18
+ compareAtPriceMinor: z.ZodNullable<z.ZodNumber>;
19
+ currencyCode: z.ZodString;
20
+ purchasableQuantity: z.ZodNumber;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ variantId: z.ZodString;
23
+ status: z.ZodLiteral<"unavailable">;
24
+ }, z.core.$strip>], "status">;
25
+ export type ReconciledCartLine = z.infer<typeof reconciledCartLineSchema>;
13
26
  declare class CanopyApiGateway {
14
27
  private apiHost;
15
28
  private baseUrl;
@@ -30,6 +43,18 @@ declare class CanopyApiGateway {
30
43
  };
31
44
  } | undefined;
32
45
  }>;
46
+ /**
47
+ * The catalog's current answer for a set of cookie-cart lines: per line,
48
+ * the live price and how many units are actually purchasable. Used to
49
+ * reconcile the client-persisted cart, which otherwise never re-reads the
50
+ * catalog facts it snapshotted at add-to-cart time.
51
+ */
52
+ reconcileCartLines({ lines, }: {
53
+ lines: {
54
+ variantId: string;
55
+ quantity: number;
56
+ }[];
57
+ }): Promise<ReconciledCartLine[]>;
33
58
  private _cartPost;
34
59
  cartGet({ cartId }: {
35
60
  cartId: string;
@@ -32,6 +32,23 @@ const loaderInvokeResponseSchema = z.object({
32
32
  })
33
33
  }).optional()
34
34
  });
35
+ const reconciledCartLineSchema = z.discriminatedUnion("status", [
36
+ z.object({
37
+ variantId: z.string(),
38
+ status: z.literal("purchasable"),
39
+ unitPriceMinor: z.number().int(),
40
+ compareAtPriceMinor: z.number().int().nullable(),
41
+ currencyCode: z.string(),
42
+ purchasableQuantity: z.number().int().min(0)
43
+ }),
44
+ z.object({
45
+ variantId: z.string(),
46
+ status: z.literal("unavailable")
47
+ })
48
+ ]);
49
+ const reconcileCartLinesResponseSchema = z.object({
50
+ lines: z.array(reconciledCartLineSchema)
51
+ });
35
52
  class CanopyApiGateway {
36
53
  apiHost;
37
54
  baseUrl;
@@ -112,6 +129,29 @@ If you're running locally, make sure the canopy-api cloudflare worker is running
112
129
  }
113
130
  return loaderInvokeResponseSchema.parse(await response.json());
114
131
  }
132
+ /**
133
+ * The catalog's current answer for a set of cookie-cart lines: per line,
134
+ * the live price and how many units are actually purchasable. Used to
135
+ * reconcile the client-persisted cart, which otherwise never re-reads the
136
+ * catalog facts it snapshotted at add-to-cart time.
137
+ */
138
+ async reconcileCartLines({
139
+ lines
140
+ }) {
141
+ const env = await getEnv();
142
+ const response = await this._post(
143
+ `${this.baseUrl}/api/v1/product-catalog/reconcile-cart-lines`,
144
+ { projectId: env.PROJECT_ID, lines }
145
+ );
146
+ if (!response.ok) {
147
+ const errorBody = await response.text().catch(() => "");
148
+ throw new CanopyApiGatewayError({
149
+ message: `Failed to reconcile cart lines: ${response.status} ${response.statusText}${errorBody ? ` \u2014 ${errorBody}` : ""}`,
150
+ statusCode: response.status
151
+ });
152
+ }
153
+ return reconcileCartLinesResponseSchema.parse(await response.json()).lines;
154
+ }
115
155
  // ---------------------------------------------------------------------------
116
156
  // Cart operations (canopy-api-backed ExternalCart)
117
157
  // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../gateways/canopy-api.ts"],
4
- "sourcesContent": ["import type { Cart } from \"../cart/cart-schema\";\n\nimport { z } from \"zod\";\n\nimport { cartSchema } from \"../cart/cart-schema\";\nimport { getEnv } from \"../env\";\nimport { CanopyError } from \"../lib/canopy-error\";\nimport { buildBaseUrl } from \"../lib/url-utils\";\n\ntype CanopyApiGatewayErrorConfig = {\n message: string;\n statusCode?: number;\n cause?: unknown;\n additionalData?: Record<string, unknown>;\n};\n\nexport class CanopyApiGatewayError extends CanopyError {\n statusCode: number;\n\n constructor(config: CanopyApiGatewayErrorConfig) {\n const resolvedStatusCode = config.statusCode ?? 500;\n super({\n message: config.message,\n cause: config.cause,\n additionalData: {\n ...config.additionalData,\n statusCode: resolvedStatusCode,\n },\n });\n this.statusCode = resolvedStatusCode;\n }\n}\n\nclass UnknownCanopyApiError extends CanopyApiGatewayError {\n constructor(config: Omit<CanopyApiGatewayErrorConfig, \"statusCode\">) {\n super({ ...config, statusCode: 502 });\n }\n}\n\nconst loaderInvokeResponseSchema = z.object({\n data: z.unknown(),\n meta: z\n .object({\n cache: z.object({\n hit: z.boolean(),\n ttlSeconds: z.number(),\n }),\n })\n .optional(),\n});\n\nclass CanopyApiGateway {\n private apiHost: string;\n private baseUrl: string;\n constructor(apiHost: string) {\n this.apiHost = apiHost;\n this.baseUrl = buildBaseUrl(apiHost);\n }\n\n private static readonly REQUEST_TIMEOUT_MILLISECONDS = 10_000;\n\n static async setup() {\n const env = await getEnv();\n\n return new CanopyApiGateway(env.CANOPY_API_HOST);\n }\n\n private async _post(url: string, body: unknown) {\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n try {\n return await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: abortController.signal,\n });\n } catch (error) {\n let message = `Failed to POST to canopy-api at ${url}: ${error}`;\n if (process.env.NODE_ENV !== \"production\") {\n message += `\\n\\napiHost: ${this.apiHost}\\nIf you're running locally, make sure the canopy-api cloudflare worker is running. You may need to restart the dev server.`;\n }\n throw new UnknownCanopyApiError({ message, cause: error });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n private async _get(url: string) {\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n try {\n return await fetch(url, { signal: abortController.signal });\n } catch (error) {\n let message = `Failed to GET from canopy-api at ${url}: ${error}`;\n if (process.env.NODE_ENV !== \"production\") {\n message += `\\n\\napiHost: ${this.apiHost}\\nIf you're running locally, make sure the canopy-api cloudflare worker is running. You may need to restart the dev server.`;\n }\n throw new UnknownCanopyApiError({ message, cause: error });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async invokeLoader({\n loaderKey,\n args,\n }: {\n loaderKey: string;\n args: Record<string, unknown>;\n }) {\n const env = await getEnv();\n const response = await this._post(`${this.baseUrl}/api/v1/loaders/invoke`, {\n projectId: env.PROJECT_ID,\n loaderKey,\n args,\n // The builder preview must render a product the merchant hasn't launched\n // yet; a published storefront must not. Only the sandbox dev server sets\n // IS_REPLO_SANDBOX, so it is what separates the two.\n includeInactiveProducts: Boolean(process.env.IS_REPLO_SANDBOX),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new CanopyApiGatewayError({\n message: `Failed to invoke loader ${loaderKey}: ${response.status} ${response.statusText}${errorBody ? ` \u2014 ${errorBody}` : \"\"}`,\n statusCode: response.status,\n });\n }\n\n return loaderInvokeResponseSchema.parse(await response.json());\n }\n\n // ---------------------------------------------------------------------------\n // Cart operations (canopy-api-backed ExternalCart)\n // ---------------------------------------------------------------------------\n\n private async _cartPost(\n path: string,\n body: Record<string, unknown>,\n ): Promise<Cart> {\n const env = await getEnv();\n const url = `${this.baseUrl}/api/v1/cart${path}`;\n\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ ...body, projectId: env.PROJECT_ID }),\n signal: abortController.signal,\n });\n } catch (error) {\n throw new UnknownCanopyApiError({\n message: `Failed to POST cart operation to ${url}: ${error}`,\n cause: error,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new CanopyApiGatewayError({\n message: `Cart operation ${path} failed: ${response.status} ${response.statusText} \u2014 ${text}`,\n statusCode: response.status,\n });\n }\n\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const json = (await response.json()) as { data: unknown };\n return cartSchema.parse(json.data);\n }\n\n async cartGet({ cartId }: { cartId: string }): Promise<Cart | null> {\n try {\n return await this._cartPost(\"/get\", { cartId });\n } catch (error) {\n if (error instanceof CanopyApiGatewayError && error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n async cartCreate(options?: {\n lines?: {\n merchandiseId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n discountCodes?: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/create\", {\n lines: options?.lines,\n discountCodes: options?.discountCodes,\n });\n }\n\n async cartAddLines({\n cartId,\n lines,\n }: {\n cartId: string;\n lines: {\n merchandiseId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n }): Promise<Cart> {\n return this._cartPost(\"/add-lines\", { cartId, lines });\n }\n\n async cartUpdateLines({\n cartId,\n lines,\n }: {\n cartId: string;\n lines: {\n lineId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n }): Promise<Cart> {\n return this._cartPost(\"/update-lines\", { cartId, lines });\n }\n\n async cartRemoveLines({\n cartId,\n lineIds,\n }: {\n cartId: string;\n lineIds: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/remove-lines\", { cartId, lineIds });\n }\n\n async cartUpdateDiscountCodes({\n cartId,\n discountCodes,\n }: {\n cartId: string;\n discountCodes: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/update-discount-codes\", { cartId, discountCodes });\n }\n}\n\nexport async function getCanopyApiGateway() {\n return CanopyApiGateway.setup();\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Cart } from \"../cart/cart-schema\";\n\nimport { z } from \"zod\";\n\nimport { cartSchema } from \"../cart/cart-schema\";\nimport { getEnv } from \"../env\";\nimport { CanopyError } from \"../lib/canopy-error\";\nimport { buildBaseUrl } from \"../lib/url-utils\";\n\ntype CanopyApiGatewayErrorConfig = {\n message: string;\n statusCode?: number;\n cause?: unknown;\n additionalData?: Record<string, unknown>;\n};\n\nexport class CanopyApiGatewayError extends CanopyError {\n statusCode: number;\n\n constructor(config: CanopyApiGatewayErrorConfig) {\n const resolvedStatusCode = config.statusCode ?? 500;\n super({\n message: config.message,\n cause: config.cause,\n additionalData: {\n ...config.additionalData,\n statusCode: resolvedStatusCode,\n },\n });\n this.statusCode = resolvedStatusCode;\n }\n}\n\nclass UnknownCanopyApiError extends CanopyApiGatewayError {\n constructor(config: Omit<CanopyApiGatewayErrorConfig, \"statusCode\">) {\n super({ ...config, statusCode: 502 });\n }\n}\n\nconst loaderInvokeResponseSchema = z.object({\n data: z.unknown(),\n meta: z\n .object({\n cache: z.object({\n hit: z.boolean(),\n ttlSeconds: z.number(),\n }),\n })\n .optional(),\n});\n\nconst reconciledCartLineSchema = z.discriminatedUnion(\"status\", [\n z.object({\n variantId: z.string(),\n status: z.literal(\"purchasable\"),\n unitPriceMinor: z.number().int(),\n compareAtPriceMinor: z.number().int().nullable(),\n currencyCode: z.string(),\n purchasableQuantity: z.number().int().min(0),\n }),\n z.object({\n variantId: z.string(),\n status: z.literal(\"unavailable\"),\n }),\n]);\n\nconst reconcileCartLinesResponseSchema = z.object({\n lines: z.array(reconciledCartLineSchema),\n});\n\nexport type ReconciledCartLine = z.infer<typeof reconciledCartLineSchema>;\n\nclass CanopyApiGateway {\n private apiHost: string;\n private baseUrl: string;\n constructor(apiHost: string) {\n this.apiHost = apiHost;\n this.baseUrl = buildBaseUrl(apiHost);\n }\n\n private static readonly REQUEST_TIMEOUT_MILLISECONDS = 10_000;\n\n static async setup() {\n const env = await getEnv();\n\n return new CanopyApiGateway(env.CANOPY_API_HOST);\n }\n\n private async _post(url: string, body: unknown) {\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n try {\n return await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: abortController.signal,\n });\n } catch (error) {\n let message = `Failed to POST to canopy-api at ${url}: ${error}`;\n if (process.env.NODE_ENV !== \"production\") {\n message += `\\n\\napiHost: ${this.apiHost}\\nIf you're running locally, make sure the canopy-api cloudflare worker is running. You may need to restart the dev server.`;\n }\n throw new UnknownCanopyApiError({ message, cause: error });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n private async _get(url: string) {\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n try {\n return await fetch(url, { signal: abortController.signal });\n } catch (error) {\n let message = `Failed to GET from canopy-api at ${url}: ${error}`;\n if (process.env.NODE_ENV !== \"production\") {\n message += `\\n\\napiHost: ${this.apiHost}\\nIf you're running locally, make sure the canopy-api cloudflare worker is running. You may need to restart the dev server.`;\n }\n throw new UnknownCanopyApiError({ message, cause: error });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async invokeLoader({\n loaderKey,\n args,\n }: {\n loaderKey: string;\n args: Record<string, unknown>;\n }) {\n const env = await getEnv();\n const response = await this._post(`${this.baseUrl}/api/v1/loaders/invoke`, {\n projectId: env.PROJECT_ID,\n loaderKey,\n args,\n // The builder preview must render a product the merchant hasn't launched\n // yet; a published storefront must not. Only the sandbox dev server sets\n // IS_REPLO_SANDBOX, so it is what separates the two.\n includeInactiveProducts: Boolean(process.env.IS_REPLO_SANDBOX),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new CanopyApiGatewayError({\n message: `Failed to invoke loader ${loaderKey}: ${response.status} ${response.statusText}${errorBody ? ` \u2014 ${errorBody}` : \"\"}`,\n statusCode: response.status,\n });\n }\n\n return loaderInvokeResponseSchema.parse(await response.json());\n }\n\n /**\n * The catalog's current answer for a set of cookie-cart lines: per line,\n * the live price and how many units are actually purchasable. Used to\n * reconcile the client-persisted cart, which otherwise never re-reads the\n * catalog facts it snapshotted at add-to-cart time.\n */\n async reconcileCartLines({\n lines,\n }: {\n lines: { variantId: string; quantity: number }[];\n }): Promise<ReconciledCartLine[]> {\n const env = await getEnv();\n const response = await this._post(\n `${this.baseUrl}/api/v1/product-catalog/reconcile-cart-lines`,\n { projectId: env.PROJECT_ID, lines },\n );\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new CanopyApiGatewayError({\n message: `Failed to reconcile cart lines: ${response.status} ${response.statusText}${errorBody ? ` \u2014 ${errorBody}` : \"\"}`,\n statusCode: response.status,\n });\n }\n\n return reconcileCartLinesResponseSchema.parse(await response.json()).lines;\n }\n\n // ---------------------------------------------------------------------------\n // Cart operations (canopy-api-backed ExternalCart)\n // ---------------------------------------------------------------------------\n\n private async _cartPost(\n path: string,\n body: Record<string, unknown>,\n ): Promise<Cart> {\n const env = await getEnv();\n const url = `${this.baseUrl}/api/v1/cart${path}`;\n\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, CanopyApiGateway.REQUEST_TIMEOUT_MILLISECONDS);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ ...body, projectId: env.PROJECT_ID }),\n signal: abortController.signal,\n });\n } catch (error) {\n throw new UnknownCanopyApiError({\n message: `Failed to POST cart operation to ${url}: ${error}`,\n cause: error,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new CanopyApiGatewayError({\n message: `Cart operation ${path} failed: ${response.status} ${response.statusText} \u2014 ${text}`,\n statusCode: response.status,\n });\n }\n\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const json = (await response.json()) as { data: unknown };\n return cartSchema.parse(json.data);\n }\n\n async cartGet({ cartId }: { cartId: string }): Promise<Cart | null> {\n try {\n return await this._cartPost(\"/get\", { cartId });\n } catch (error) {\n if (error instanceof CanopyApiGatewayError && error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n async cartCreate(options?: {\n lines?: {\n merchandiseId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n discountCodes?: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/create\", {\n lines: options?.lines,\n discountCodes: options?.discountCodes,\n });\n }\n\n async cartAddLines({\n cartId,\n lines,\n }: {\n cartId: string;\n lines: {\n merchandiseId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n }): Promise<Cart> {\n return this._cartPost(\"/add-lines\", { cartId, lines });\n }\n\n async cartUpdateLines({\n cartId,\n lines,\n }: {\n cartId: string;\n lines: {\n lineId: string;\n quantity: number;\n attributes?: { key: string; value: string }[];\n sellingPlanId?: string | null;\n }[];\n }): Promise<Cart> {\n return this._cartPost(\"/update-lines\", { cartId, lines });\n }\n\n async cartRemoveLines({\n cartId,\n lineIds,\n }: {\n cartId: string;\n lineIds: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/remove-lines\", { cartId, lineIds });\n }\n\n async cartUpdateDiscountCodes({\n cartId,\n discountCodes,\n }: {\n cartId: string;\n discountCodes: string[];\n }): Promise<Cart> {\n return this._cartPost(\"/update-discount-codes\", { cartId, discountCodes });\n }\n}\n\nexport async function getCanopyApiGateway() {\n return CanopyApiGateway.setup();\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  export const BUILD_METADATA = {
2
2
  "packageName": "@replohq/sdk",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "branch": "HEAD",
5
- "commit": "26358ebb6719c706ba541c3b75687181c732615c",
6
- "builtAt": "2026-09-09T19:22:13.298Z"
5
+ "commit": "4864322a9ff1f3dd385fee9bc0010f4535520cbb",
6
+ "builtAt": "2026-09-10T21:47:40.227Z"
7
7
  };
@@ -193,6 +193,7 @@ export declare const variantSchema: z.ZodObject<{
193
193
  id: z.ZodString;
194
194
  title: z.ZodOptional<z.ZodString>;
195
195
  availableForSale: z.ZodOptional<z.ZodBoolean>;
196
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
196
197
  sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
197
198
  selectedOptions: z.ZodOptional<z.ZodArray<z.ZodObject<{
198
199
  name: z.ZodString;
@@ -250,6 +251,7 @@ export declare const productSchema: z.ZodObject<{
250
251
  id: z.ZodString;
251
252
  title: z.ZodOptional<z.ZodString>;
252
253
  availableForSale: z.ZodOptional<z.ZodBoolean>;
254
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
253
255
  sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
254
256
  selectedOptions: z.ZodOptional<z.ZodArray<z.ZodObject<{
255
257
  name: z.ZodString;
@@ -380,6 +382,7 @@ export declare const fullVariantSchema: z.ZodObject<{
380
382
  id: z.ZodString;
381
383
  title: z.ZodString;
382
384
  availableForSale: z.ZodBoolean;
385
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
383
386
  sku: z.ZodNullable<z.ZodString>;
384
387
  selectedOptions: z.ZodArray<z.ZodObject<{
385
388
  name: z.ZodString;
@@ -437,6 +440,7 @@ export declare const fullProductSchema: z.ZodObject<{
437
440
  id: z.ZodString;
438
441
  title: z.ZodString;
439
442
  availableForSale: z.ZodBoolean;
443
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
440
444
  sku: z.ZodNullable<z.ZodString>;
441
445
  selectedOptions: z.ZodArray<z.ZodObject<{
442
446
  name: z.ZodString;
@@ -597,6 +601,7 @@ export declare const paginatedProductsSchema: z.ZodObject<{
597
601
  id: z.ZodString;
598
602
  title: z.ZodOptional<z.ZodString>;
599
603
  availableForSale: z.ZodOptional<z.ZodBoolean>;
604
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
600
605
  sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
601
606
  selectedOptions: z.ZodOptional<z.ZodArray<z.ZodObject<{
602
607
  name: z.ZodString;
@@ -105,6 +105,7 @@ const variantSchema = z.object({
105
105
  id: z.string(),
106
106
  title: z.string().optional(),
107
107
  availableForSale: z.boolean().optional(),
108
+ isLowStock: z.boolean().optional(),
108
109
  sku: z.string().nullish(),
109
110
  selectedOptions: z.array(selectedOptionSchema).optional(),
110
111
  image: imageSchema.nullish(),
@@ -152,6 +153,7 @@ const fullVariantSchema = z.object({
152
153
  id: z.string(),
153
154
  title: z.string(),
154
155
  availableForSale: z.boolean(),
156
+ isLowStock: z.boolean().optional(),
155
157
  sku: z.string().nullable(),
156
158
  selectedOptions: z.array(selectedOptionSchema),
157
159
  image: imageSchema.nullable(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../loaders/loader-schemas.ts"],
4
- "sourcesContent": ["import { z } from \"zod\";\n\n// NOTE (Ryan, 2026-07-23, REPL-27611): Self-contained copies of the loader\n// output contracts (and the `objectType` / `sellingPlan` sub-schemas they\n// compose) that the SDK validates on published pages. These live here \u2014 not\n// imported from `schemas` \u2014 so nothing shipped to a generated site depends on\n// the `schemas` workspace package. The backend keeps the canonical definitions\n// in `schemas` because its integration registry + tool-metadata generation\n// consume them and cannot depend on the SDK without an import cycle. The two\n// sides are kept structurally in lockstep by `loader-schemas.spec.ts`.\n\n// ---------------------------------------------------------------------------\n// Shared sub-schemas (mirrors of schemas/objectType.ts)\n// ---------------------------------------------------------------------------\n\nexport const imageSchema = z.object({\n url: z.string(),\n altText: z.string().nullable(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const mediaImageSchema = z.object({\n type: z.literal(\"image\"),\n alt: z.string().nullable(),\n url: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const videoSourceSchema = z.object({\n url: z.string(),\n mimeType: z.string(),\n format: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const previewImageSchema = z.object({\n alt: z.string().nullable(),\n url: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const videoSchema = z.object({\n type: z.literal(\"video\"),\n alt: z.string().nullable(),\n sources: z.array(videoSourceSchema),\n previewImage: previewImageSchema.nullable(),\n});\n\nexport const externalVideoSchema = z.object({\n type: z.literal(\"externalVideo\"),\n alt: z.string().nullable(),\n embedUrl: z.string(),\n host: z.string(),\n originUrl: z.string(),\n previewImage: previewImageSchema.nullable(),\n});\n\nexport const mediaSchema = z.discriminatedUnion(\"type\", [\n mediaImageSchema,\n videoSchema,\n externalVideoSchema,\n]);\n\nexport const priceSchema = z.object({\n amount: z.string(),\n currencyCode: z.string(),\n});\n\nexport const selectedOptionSchema = z.object({\n name: z.string(),\n value: z.string(),\n});\n\nexport const optionValueSwatchSchema = z.object({\n color: z.string().nullable(),\n imageUrl: z.string().nullable(),\n});\n\nexport const optionValueSchema = z.object({\n id: z.string(),\n value: z.string(),\n swatch: optionValueSwatchSchema.nullable(),\n});\n\nexport const productOptionSchema = z.object({\n id: z.string().optional(),\n name: z.string(),\n values: z.array(z.string()),\n optionValues: z.array(optionValueSchema).optional(),\n});\n\nexport const metafieldSchema = z.object({\n key: z.string(),\n namespace: z.string(),\n type: z.string(),\n value: z.string(),\n});\n\n// ---------------------------------------------------------------------------\n// Selling plan schemas (mirror of schemas/sellingPlan.ts)\n// ---------------------------------------------------------------------------\n\nexport const sellingPlanPriceAdjustmentSchema = z.object({\n value: z.number(),\n valueType: z.enum([\"percentage\", \"fixedAmount\", \"price\"]),\n});\n\nexport const sellingPlanOptionValueSchema = z.object({\n name: z.string().optional(),\n value: z.string(),\n});\n\nexport const sellingPlanSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n optionValues: z.array(sellingPlanOptionValueSchema),\n priceAdjustments: z.array(sellingPlanPriceAdjustmentSchema),\n appId: z.string().nullish(),\n price: z.string().optional(),\n externalId: z.string().nullable(),\n});\n\nexport const sellingPlanGroupSchema = z\n .object({\n appId: z.string().nullable(),\n options: z.array(\n z.object({\n name: z.string(),\n values: z.array(z.union([z.string(), z.null()])),\n }),\n ),\n sellingPlans: z.array(sellingPlanSchema),\n })\n .describe(\"SellingPlanGroup\");\n\nexport type SellingPlanGroup = z.infer<typeof sellingPlanGroupSchema>;\n\n// ---------------------------------------------------------------------------\n// Canonical Product / Variant (mostly-optional; mirror of objectType.ts).\n// Used by the collection-products (paginated) and rebuy loaders, and as the\n// cart's cache-resolution product shape.\n// ---------------------------------------------------------------------------\n\nexport const variantSchema = z.object({\n id: z.string(),\n title: z.string().optional(),\n availableForSale: z.boolean().optional(),\n sku: z.string().nullish(),\n selectedOptions: z.array(selectedOptionSchema).optional(),\n image: imageSchema.nullish(),\n price: priceSchema.optional(),\n compareAtPrice: priceSchema.nullish(),\n sellingPlanIds: z.array(z.string()).optional(),\n});\n\nexport const productSchema = z.object({\n id: z.string(),\n handle: z.string().optional(),\n title: z.string().optional(),\n description: z.string().nullish(),\n descriptionHtml: z.string().nullish(),\n availableForSale: z.boolean().optional(),\n // NOTE (Berkley, 2026-07-30): Admin-sourced status; Storefront loader data\n // never includes it. Kept in lockstep with `schemas/objectType` by the\n // drift-guard spec.\n status: z.enum([\"ACTIVE\", \"DRAFT\", \"ARCHIVED\", \"UNLISTED\"]).optional(),\n featuredImage: imageSchema.nullish(),\n options: z.array(productOptionSchema).optional(),\n variants: z.array(variantSchema).optional(),\n minPrice: priceSchema.optional(),\n maxPrice: priceSchema.optional(),\n compareAtMinPrice: priceSchema.optional(),\n compareAtMaxPrice: priceSchema.optional(),\n images: z.array(imageSchema).optional(),\n media: z.array(mediaSchema).optional(),\n vendor: z.string().nullish(),\n productType: z.string().nullish(),\n tags: z.array(z.string()).optional(),\n sellingPlanGroups: z.array(sellingPlanGroupSchema).optional(),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport type Product = z.infer<typeof productSchema>;\n\nexport const okendoReviewSchema = z\n .object({\n id: z.string(),\n title: z.string().optional(),\n body: z.string().optional(),\n rating: z.number().optional(),\n productName: z.string().optional(),\n reviewerName: z.string().optional(),\n dateCreated: z.string().optional(),\n status: z.string().optional(),\n })\n .describe(\"OkendoReview\");\n\n// ---------------------------------------------------------------------------\n// Full loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/product.ts)\n// ---------------------------------------------------------------------------\n\nexport const fullVariantSchema = z.object({\n id: z.string(),\n title: z.string(),\n availableForSale: z.boolean(),\n sku: z.string().nullable(),\n selectedOptions: z.array(selectedOptionSchema),\n image: imageSchema.nullable(),\n price: priceSchema,\n compareAtPrice: priceSchema.nullable(),\n sellingPlanIds: z.array(z.string()),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport const fullProductSchema = z.object({\n id: z.string(),\n handle: z.string(),\n title: z.string(),\n description: z.string().nullable(),\n descriptionHtml: z.string().nullable(),\n availableForSale: z.boolean(),\n featuredImage: imageSchema.nullable(),\n options: z.array(productOptionSchema),\n variants: z.array(fullVariantSchema),\n images: z.array(imageSchema),\n media: z.array(mediaSchema),\n vendor: z.string().nullable(),\n productType: z.string().nullable(),\n tags: z.array(z.string()),\n sellingPlanGroups: z.array(sellingPlanGroupSchema),\n metafields: z.array(metafieldSchema),\n});\n\nexport const fullCollectionSchema = z.object({\n id: z.string(),\n handle: z.string(),\n title: z.string(),\n descriptionHtml: z.string().nullable(),\n image: imageSchema.nullable(),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport const paginatedProductsSchema = z.object({\n products: z.array(productSchema),\n pageInfo: z.object({\n hasNextPage: z.boolean(),\n endCursor: z.string().nullable(),\n }),\n});\n\nexport type FullProduct = z.infer<typeof fullProductSchema>;\nexport type FullCollection = z.infer<typeof fullCollectionSchema>;\nexport type FullVariant = z.infer<typeof fullVariantSchema>;\nexport type PaginatedProducts = z.infer<typeof paginatedProductsSchema>;\n\n// ---------------------------------------------------------------------------\n// Levanta loader output (mirror of\n// schemas/agentTools/customIntegrations/loaders/levanta.ts)\n// ---------------------------------------------------------------------------\n\nconst levantaAffiliateLinkSchema = z.object({\n linkId: z.string(),\n url: z.string(),\n});\n\nexport const levantaProductFullSchema = z\n .object({\n id: z.string(),\n asin: z.string(),\n title: z.string(),\n price: z\n .string()\n .describe('Product price as a decimal string in USD (e.g. \"34.99\").'),\n commission: z\n .string()\n .describe(\n 'Creator commission rate as a decimal string percentage (e.g. \"8.5\" meaning 8.5%).',\n ),\n imageUrl: z.string().nullable(),\n brand: z.object({ id: z.string(), name: z.string() }).nullable(),\n inStock: z.boolean(),\n marketplace: z.string(),\n affiliateLink: levantaAffiliateLinkSchema.nullable(),\n })\n .describe(\"LevantaProductFull\");\n\nexport type LevantaProductFull = z.infer<typeof levantaProductFullSchema>;\n\n// ---------------------------------------------------------------------------\n// Yotpo loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/yotpo.ts)\n// ---------------------------------------------------------------------------\n\nexport const yotpoReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n content: z.string().nullable(),\n score: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n});\n\nexport const yotpoProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(yotpoReviewLoaderItemSchema),\n});\n\nexport const yotpoProductReviewAggregateLoaderOutputSchema = z.object({\n averageScore: z.number(),\n totalReviews: z.number(),\n starDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Reviews.io loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/reviewsIo.ts)\n// ---------------------------------------------------------------------------\n\nexport const reviewsIoReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n body: z.string().nullable(),\n rating: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n productName: z.string().nullable(),\n sku: z.string().nullable(),\n});\n\nexport const reviewsIoProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(reviewsIoReviewLoaderItemSchema),\n reviewCount: z.number(),\n reviewAverageValue: z.number(),\n});\n\nexport const reviewsIoProductReviewAggregateLoaderOutputSchema = z.object({\n reviewCount: z.number(),\n reviewAverageValue: z.number(),\n});\n\n// ---------------------------------------------------------------------------\n// Loox loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/loox.ts)\n// ---------------------------------------------------------------------------\n\nexport const looxReviewMediaSchema = z.object({\n type: z.string().nullable(),\n url: z.string(),\n thumbnailUrl: z.string().nullable(),\n});\n\nexport const looxReviewLoaderItemSchema = z.object({\n id: z.string(),\n rating: z.number().nullable(),\n body: z.string().nullable(),\n createdAt: z.string().nullable(),\n verified: z.boolean(),\n reviewerName: z.string().nullable(),\n productName: z.string().nullable(),\n media: z.array(looxReviewMediaSchema),\n});\n\nexport const looxProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(looxReviewLoaderItemSchema),\n});\n\nexport const looxProductReviewAggregateLoaderOutputSchema = z.object({\n totalReviews: z.number(),\n averageRating: z.number(),\n ratingDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Judge.me loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/judgeme.ts)\n// ---------------------------------------------------------------------------\n\nexport const judgemeReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n content: z.string().nullable(),\n score: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n});\n\nexport const judgemeProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(judgemeReviewLoaderItemSchema),\n});\n\nexport const judgemeProductReviewAggregateLoaderOutputSchema = z.object({\n averageScore: z.number(),\n totalReviews: z.number(),\n starDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Statsig loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/statsig.ts)\n// ---------------------------------------------------------------------------\n\nexport const statsigExperimentLoaderOutputSchema = z.object({\n experimentName: z.string(),\n groupName: z\n .string()\n .nullable()\n .describe(\"The assigned variant group name (e.g. Control, Test).\"),\n ruleId: z\n .string()\n .nullable()\n .describe(\"The Statsig rule ID that produced this assignment.\"),\n value: z\n .record(z.string(), z.unknown())\n .describe(\"The parameter values for the assigned group.\"),\n reason: z\n .string()\n .describe(\"The evaluation reason reported by Statsig (for debugging).\"),\n});\n\nexport type StatsigExperimentAssignment = z.infer<\n typeof statsigExperimentLoaderOutputSchema\n>;\n\n// ---------------------------------------------------------------------------\n// Contentful loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/contentful.ts)\n// ---------------------------------------------------------------------------\n\nexport const contentfulEntryObjectSchema = z\n .object({\n id: z.string(),\n contentTypeId: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n fields: z.record(z.string(), z.unknown()),\n })\n .describe(\"ContentfulEntryObject\");\n\nexport const contentfulAssetObjectSchema = z\n .object({\n id: z.string(),\n title: z.string().nullable(),\n description: z.string().nullable(),\n fileName: z.string().nullable(),\n contentType: z.string().nullable(),\n url: z.string().nullable(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n })\n .describe(\"ContentfulAssetObject\");\n\nexport const contentfulIncludesSchema = z\n .object({\n entries: z.array(contentfulEntryObjectSchema),\n assets: z.array(contentfulAssetObjectSchema),\n })\n .describe(\"ContentfulIncludes\");\n\nexport const contentfulEntryLoaderOutputSchema = z\n .object({\n entry: contentfulEntryObjectSchema,\n includes: contentfulIncludesSchema,\n })\n .describe(\"ContentfulEntryLoaderOutput\");\n\nexport const contentfulEntriesLoaderOutputSchema = z\n .object({\n items: z.array(contentfulEntryObjectSchema),\n includes: contentfulIncludesSchema,\n total: z.number(),\n skip: z.number(),\n limit: z.number(),\n })\n .describe(\"ContentfulEntriesLoaderOutput\");\n\nexport type ContentfulEntryObject = z.infer<typeof contentfulEntryObjectSchema>;\nexport type ContentfulAssetObject = z.infer<typeof contentfulAssetObjectSchema>;\nexport type ContentfulEntryLoaderOutput = z.infer<\n typeof contentfulEntryLoaderOutputSchema\n>;\nexport type ContentfulEntriesLoaderOutput = z.infer<\n typeof contentfulEntriesLoaderOutputSchema\n>;\n\n// ---------------------------------------------------------------------------\n// Shopify metaobjects (mirror of\n// schemas/agentTools/customIntegrations/loaders/shopify.ts)\n// ---------------------------------------------------------------------------\n\nexport const storefrontMetaobjectSchema = z\n .object({\n id: z.string(),\n type: z.string(),\n handle: z.string(),\n updatedAt: z.string().nullable(),\n fields: z.array(\n z.object({\n key: z.string(),\n type: z.string(),\n value: z.string().nullable(),\n }),\n ),\n })\n .describe(\"StorefrontMetaobject\");\n\nexport const shopifyMetaobjectLoaderOutputSchema = storefrontMetaobjectSchema;\n\nexport const shopifyMetaobjectsLoaderOutputSchema = z\n .object({\n metaobjects: z.array(storefrontMetaobjectSchema),\n pageInfo: z.object({\n hasNextPage: z.boolean(),\n endCursor: z.string().nullable(),\n }),\n })\n .describe(\"ShopifyMetaobjectsLoaderOutput\");\n\nexport type StorefrontMetaobject = z.infer<typeof storefrontMetaobjectSchema>;\nexport type ShopifyMetaobjectLoaderOutput = z.infer<\n typeof shopifyMetaobjectLoaderOutputSchema\n>;\nexport type ShopifyMetaobjectsLoaderOutput = z.infer<\n typeof shopifyMetaobjectsLoaderOutputSchema\n>;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from \"zod\";\n\n// NOTE (Ryan, 2026-07-23, REPL-27611): Self-contained copies of the loader\n// output contracts (and the `objectType` / `sellingPlan` sub-schemas they\n// compose) that the SDK validates on published pages. These live here \u2014 not\n// imported from `schemas` \u2014 so nothing shipped to a generated site depends on\n// the `schemas` workspace package. The backend keeps the canonical definitions\n// in `schemas` because its integration registry + tool-metadata generation\n// consume them and cannot depend on the SDK without an import cycle. The two\n// sides are kept structurally in lockstep by `loader-schemas.spec.ts`.\n\n// ---------------------------------------------------------------------------\n// Shared sub-schemas (mirrors of schemas/objectType.ts)\n// ---------------------------------------------------------------------------\n\nexport const imageSchema = z.object({\n url: z.string(),\n altText: z.string().nullable(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const mediaImageSchema = z.object({\n type: z.literal(\"image\"),\n alt: z.string().nullable(),\n url: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const videoSourceSchema = z.object({\n url: z.string(),\n mimeType: z.string(),\n format: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const previewImageSchema = z.object({\n alt: z.string().nullable(),\n url: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n});\n\nexport const videoSchema = z.object({\n type: z.literal(\"video\"),\n alt: z.string().nullable(),\n sources: z.array(videoSourceSchema),\n previewImage: previewImageSchema.nullable(),\n});\n\nexport const externalVideoSchema = z.object({\n type: z.literal(\"externalVideo\"),\n alt: z.string().nullable(),\n embedUrl: z.string(),\n host: z.string(),\n originUrl: z.string(),\n previewImage: previewImageSchema.nullable(),\n});\n\nexport const mediaSchema = z.discriminatedUnion(\"type\", [\n mediaImageSchema,\n videoSchema,\n externalVideoSchema,\n]);\n\nexport const priceSchema = z.object({\n amount: z.string(),\n currencyCode: z.string(),\n});\n\nexport const selectedOptionSchema = z.object({\n name: z.string(),\n value: z.string(),\n});\n\nexport const optionValueSwatchSchema = z.object({\n color: z.string().nullable(),\n imageUrl: z.string().nullable(),\n});\n\nexport const optionValueSchema = z.object({\n id: z.string(),\n value: z.string(),\n swatch: optionValueSwatchSchema.nullable(),\n});\n\nexport const productOptionSchema = z.object({\n id: z.string().optional(),\n name: z.string(),\n values: z.array(z.string()),\n optionValues: z.array(optionValueSchema).optional(),\n});\n\nexport const metafieldSchema = z.object({\n key: z.string(),\n namespace: z.string(),\n type: z.string(),\n value: z.string(),\n});\n\n// ---------------------------------------------------------------------------\n// Selling plan schemas (mirror of schemas/sellingPlan.ts)\n// ---------------------------------------------------------------------------\n\nexport const sellingPlanPriceAdjustmentSchema = z.object({\n value: z.number(),\n valueType: z.enum([\"percentage\", \"fixedAmount\", \"price\"]),\n});\n\nexport const sellingPlanOptionValueSchema = z.object({\n name: z.string().optional(),\n value: z.string(),\n});\n\nexport const sellingPlanSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n optionValues: z.array(sellingPlanOptionValueSchema),\n priceAdjustments: z.array(sellingPlanPriceAdjustmentSchema),\n appId: z.string().nullish(),\n price: z.string().optional(),\n externalId: z.string().nullable(),\n});\n\nexport const sellingPlanGroupSchema = z\n .object({\n appId: z.string().nullable(),\n options: z.array(\n z.object({\n name: z.string(),\n values: z.array(z.union([z.string(), z.null()])),\n }),\n ),\n sellingPlans: z.array(sellingPlanSchema),\n })\n .describe(\"SellingPlanGroup\");\n\nexport type SellingPlanGroup = z.infer<typeof sellingPlanGroupSchema>;\n\n// ---------------------------------------------------------------------------\n// Canonical Product / Variant (mostly-optional; mirror of objectType.ts).\n// Used by the collection-products (paginated) and rebuy loaders, and as the\n// cart's cache-resolution product shape.\n// ---------------------------------------------------------------------------\n\nexport const variantSchema = z.object({\n id: z.string(),\n title: z.string().optional(),\n availableForSale: z.boolean().optional(),\n isLowStock: z.boolean().optional(),\n sku: z.string().nullish(),\n selectedOptions: z.array(selectedOptionSchema).optional(),\n image: imageSchema.nullish(),\n price: priceSchema.optional(),\n compareAtPrice: priceSchema.nullish(),\n sellingPlanIds: z.array(z.string()).optional(),\n});\n\nexport const productSchema = z.object({\n id: z.string(),\n handle: z.string().optional(),\n title: z.string().optional(),\n description: z.string().nullish(),\n descriptionHtml: z.string().nullish(),\n availableForSale: z.boolean().optional(),\n // NOTE (Berkley, 2026-07-30): Admin-sourced status; Storefront loader data\n // never includes it. Kept in lockstep with `schemas/objectType` by the\n // drift-guard spec.\n status: z.enum([\"ACTIVE\", \"DRAFT\", \"ARCHIVED\", \"UNLISTED\"]).optional(),\n featuredImage: imageSchema.nullish(),\n options: z.array(productOptionSchema).optional(),\n variants: z.array(variantSchema).optional(),\n minPrice: priceSchema.optional(),\n maxPrice: priceSchema.optional(),\n compareAtMinPrice: priceSchema.optional(),\n compareAtMaxPrice: priceSchema.optional(),\n images: z.array(imageSchema).optional(),\n media: z.array(mediaSchema).optional(),\n vendor: z.string().nullish(),\n productType: z.string().nullish(),\n tags: z.array(z.string()).optional(),\n sellingPlanGroups: z.array(sellingPlanGroupSchema).optional(),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport type Product = z.infer<typeof productSchema>;\n\nexport const okendoReviewSchema = z\n .object({\n id: z.string(),\n title: z.string().optional(),\n body: z.string().optional(),\n rating: z.number().optional(),\n productName: z.string().optional(),\n reviewerName: z.string().optional(),\n dateCreated: z.string().optional(),\n status: z.string().optional(),\n })\n .describe(\"OkendoReview\");\n\n// ---------------------------------------------------------------------------\n// Full loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/product.ts)\n// ---------------------------------------------------------------------------\n\nexport const fullVariantSchema = z.object({\n id: z.string(),\n title: z.string(),\n availableForSale: z.boolean(),\n isLowStock: z.boolean().optional(),\n sku: z.string().nullable(),\n selectedOptions: z.array(selectedOptionSchema),\n image: imageSchema.nullable(),\n price: priceSchema,\n compareAtPrice: priceSchema.nullable(),\n sellingPlanIds: z.array(z.string()),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport const fullProductSchema = z.object({\n id: z.string(),\n handle: z.string(),\n title: z.string(),\n description: z.string().nullable(),\n descriptionHtml: z.string().nullable(),\n availableForSale: z.boolean(),\n featuredImage: imageSchema.nullable(),\n options: z.array(productOptionSchema),\n variants: z.array(fullVariantSchema),\n images: z.array(imageSchema),\n media: z.array(mediaSchema),\n vendor: z.string().nullable(),\n productType: z.string().nullable(),\n tags: z.array(z.string()),\n sellingPlanGroups: z.array(sellingPlanGroupSchema),\n metafields: z.array(metafieldSchema),\n});\n\nexport const fullCollectionSchema = z.object({\n id: z.string(),\n handle: z.string(),\n title: z.string(),\n descriptionHtml: z.string().nullable(),\n image: imageSchema.nullable(),\n metafields: z.array(metafieldSchema).optional(),\n});\n\nexport const paginatedProductsSchema = z.object({\n products: z.array(productSchema),\n pageInfo: z.object({\n hasNextPage: z.boolean(),\n endCursor: z.string().nullable(),\n }),\n});\n\nexport type FullProduct = z.infer<typeof fullProductSchema>;\nexport type FullCollection = z.infer<typeof fullCollectionSchema>;\nexport type FullVariant = z.infer<typeof fullVariantSchema>;\nexport type PaginatedProducts = z.infer<typeof paginatedProductsSchema>;\n\n// ---------------------------------------------------------------------------\n// Levanta loader output (mirror of\n// schemas/agentTools/customIntegrations/loaders/levanta.ts)\n// ---------------------------------------------------------------------------\n\nconst levantaAffiliateLinkSchema = z.object({\n linkId: z.string(),\n url: z.string(),\n});\n\nexport const levantaProductFullSchema = z\n .object({\n id: z.string(),\n asin: z.string(),\n title: z.string(),\n price: z\n .string()\n .describe('Product price as a decimal string in USD (e.g. \"34.99\").'),\n commission: z\n .string()\n .describe(\n 'Creator commission rate as a decimal string percentage (e.g. \"8.5\" meaning 8.5%).',\n ),\n imageUrl: z.string().nullable(),\n brand: z.object({ id: z.string(), name: z.string() }).nullable(),\n inStock: z.boolean(),\n marketplace: z.string(),\n affiliateLink: levantaAffiliateLinkSchema.nullable(),\n })\n .describe(\"LevantaProductFull\");\n\nexport type LevantaProductFull = z.infer<typeof levantaProductFullSchema>;\n\n// ---------------------------------------------------------------------------\n// Yotpo loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/yotpo.ts)\n// ---------------------------------------------------------------------------\n\nexport const yotpoReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n content: z.string().nullable(),\n score: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n});\n\nexport const yotpoProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(yotpoReviewLoaderItemSchema),\n});\n\nexport const yotpoProductReviewAggregateLoaderOutputSchema = z.object({\n averageScore: z.number(),\n totalReviews: z.number(),\n starDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Reviews.io loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/reviewsIo.ts)\n// ---------------------------------------------------------------------------\n\nexport const reviewsIoReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n body: z.string().nullable(),\n rating: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n productName: z.string().nullable(),\n sku: z.string().nullable(),\n});\n\nexport const reviewsIoProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(reviewsIoReviewLoaderItemSchema),\n reviewCount: z.number(),\n reviewAverageValue: z.number(),\n});\n\nexport const reviewsIoProductReviewAggregateLoaderOutputSchema = z.object({\n reviewCount: z.number(),\n reviewAverageValue: z.number(),\n});\n\n// ---------------------------------------------------------------------------\n// Loox loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/loox.ts)\n// ---------------------------------------------------------------------------\n\nexport const looxReviewMediaSchema = z.object({\n type: z.string().nullable(),\n url: z.string(),\n thumbnailUrl: z.string().nullable(),\n});\n\nexport const looxReviewLoaderItemSchema = z.object({\n id: z.string(),\n rating: z.number().nullable(),\n body: z.string().nullable(),\n createdAt: z.string().nullable(),\n verified: z.boolean(),\n reviewerName: z.string().nullable(),\n productName: z.string().nullable(),\n media: z.array(looxReviewMediaSchema),\n});\n\nexport const looxProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(looxReviewLoaderItemSchema),\n});\n\nexport const looxProductReviewAggregateLoaderOutputSchema = z.object({\n totalReviews: z.number(),\n averageRating: z.number(),\n ratingDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Judge.me loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/judgeme.ts)\n// ---------------------------------------------------------------------------\n\nexport const judgemeReviewLoaderItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable(),\n content: z.string().nullable(),\n score: z.number().nullable(),\n createdAt: z.string().nullable(),\n verifiedBuyer: z.boolean(),\n reviewerName: z.string().nullable(),\n});\n\nexport const judgemeProductReviewsLoaderOutputSchema = z.object({\n reviews: z.array(judgemeReviewLoaderItemSchema),\n});\n\nexport const judgemeProductReviewAggregateLoaderOutputSchema = z.object({\n averageScore: z.number(),\n totalReviews: z.number(),\n starDistribution: z.record(z.string(), z.number()),\n});\n\n// ---------------------------------------------------------------------------\n// Statsig loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/statsig.ts)\n// ---------------------------------------------------------------------------\n\nexport const statsigExperimentLoaderOutputSchema = z.object({\n experimentName: z.string(),\n groupName: z\n .string()\n .nullable()\n .describe(\"The assigned variant group name (e.g. Control, Test).\"),\n ruleId: z\n .string()\n .nullable()\n .describe(\"The Statsig rule ID that produced this assignment.\"),\n value: z\n .record(z.string(), z.unknown())\n .describe(\"The parameter values for the assigned group.\"),\n reason: z\n .string()\n .describe(\"The evaluation reason reported by Statsig (for debugging).\"),\n});\n\nexport type StatsigExperimentAssignment = z.infer<\n typeof statsigExperimentLoaderOutputSchema\n>;\n\n// ---------------------------------------------------------------------------\n// Contentful loader outputs (mirror of\n// schemas/agentTools/customIntegrations/loaders/contentful.ts)\n// ---------------------------------------------------------------------------\n\nexport const contentfulEntryObjectSchema = z\n .object({\n id: z.string(),\n contentTypeId: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n fields: z.record(z.string(), z.unknown()),\n })\n .describe(\"ContentfulEntryObject\");\n\nexport const contentfulAssetObjectSchema = z\n .object({\n id: z.string(),\n title: z.string().nullable(),\n description: z.string().nullable(),\n fileName: z.string().nullable(),\n contentType: z.string().nullable(),\n url: z.string().nullable(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n })\n .describe(\"ContentfulAssetObject\");\n\nexport const contentfulIncludesSchema = z\n .object({\n entries: z.array(contentfulEntryObjectSchema),\n assets: z.array(contentfulAssetObjectSchema),\n })\n .describe(\"ContentfulIncludes\");\n\nexport const contentfulEntryLoaderOutputSchema = z\n .object({\n entry: contentfulEntryObjectSchema,\n includes: contentfulIncludesSchema,\n })\n .describe(\"ContentfulEntryLoaderOutput\");\n\nexport const contentfulEntriesLoaderOutputSchema = z\n .object({\n items: z.array(contentfulEntryObjectSchema),\n includes: contentfulIncludesSchema,\n total: z.number(),\n skip: z.number(),\n limit: z.number(),\n })\n .describe(\"ContentfulEntriesLoaderOutput\");\n\nexport type ContentfulEntryObject = z.infer<typeof contentfulEntryObjectSchema>;\nexport type ContentfulAssetObject = z.infer<typeof contentfulAssetObjectSchema>;\nexport type ContentfulEntryLoaderOutput = z.infer<\n typeof contentfulEntryLoaderOutputSchema\n>;\nexport type ContentfulEntriesLoaderOutput = z.infer<\n typeof contentfulEntriesLoaderOutputSchema\n>;\n\n// ---------------------------------------------------------------------------\n// Shopify metaobjects (mirror of\n// schemas/agentTools/customIntegrations/loaders/shopify.ts)\n// ---------------------------------------------------------------------------\n\nexport const storefrontMetaobjectSchema = z\n .object({\n id: z.string(),\n type: z.string(),\n handle: z.string(),\n updatedAt: z.string().nullable(),\n fields: z.array(\n z.object({\n key: z.string(),\n type: z.string(),\n value: z.string().nullable(),\n }),\n ),\n })\n .describe(\"StorefrontMetaobject\");\n\nexport const shopifyMetaobjectLoaderOutputSchema = storefrontMetaobjectSchema;\n\nexport const shopifyMetaobjectsLoaderOutputSchema = z\n .object({\n metaobjects: z.array(storefrontMetaobjectSchema),\n pageInfo: z.object({\n hasNextPage: z.boolean(),\n endCursor: z.string().nullable(),\n }),\n })\n .describe(\"ShopifyMetaobjectsLoaderOutput\");\n\nexport type StorefrontMetaobject = z.infer<typeof storefrontMetaobjectSchema>;\nexport type ShopifyMetaobjectLoaderOutput = z.infer<\n typeof shopifyMetaobjectLoaderOutputSchema\n>;\nexport type ShopifyMetaobjectsLoaderOutput = z.infer<\n typeof shopifyMetaobjectsLoaderOutputSchema\n>;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -37,6 +37,7 @@ declare const rebuyRecommendationsOutputSchema: z.ZodObject<{
37
37
  id: z.ZodString;
38
38
  title: z.ZodOptional<z.ZodString>;
39
39
  availableForSale: z.ZodOptional<z.ZodBoolean>;
40
+ isLowStock: z.ZodOptional<z.ZodBoolean>;
40
41
  sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
41
42
  selectedOptions: z.ZodOptional<z.ZodArray<z.ZodObject<{
42
43
  name: z.ZodString;
package/next/config.d.ts CHANGED
@@ -1,4 +1,22 @@
1
1
  import type { NextConfig } from "next";
2
+ /**
3
+ * Builds the site's `next.config.ts`, layering your options over Replo's
4
+ * platform defaults (image loader, preview origins, build settings). Add keys
5
+ * freely: nested blocks are deep-merged, and platform wiring always wins, so
6
+ * setting one nested option never drops the rest of the block.
7
+ *
8
+ * Export the result as the default from `next.config.ts`. A site that needs no
9
+ * customization can re-export this module's own default instead.
10
+ *
11
+ * @param overrides Next.js config options to layer on top of the defaults.
12
+ * @returns The merged Next.js config.
13
+ * @example
14
+ * ```ts
15
+ * import { siteConfig } from "@replohq/sdk/next/config";
16
+ *
17
+ * export default siteConfig({ experimental: { typedRoutes: true } });
18
+ * ```
19
+ */
2
20
  export declare function siteConfig(overrides?: NextConfig): NextConfig;
3
21
  declare const nextConfig: NextConfig;
4
22
  export default nextConfig;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../next/config.ts"],
4
- "sourcesContent": ["import { existsSync } from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport type { NextConfig } from \"next\";\n\n// Origins browsers load sandbox previews from \u2014 PREVIEW_HOSTNAME in the\n// coordinator's wrangler.jsonc plus Daytona's native preview domain. Next 16\n// hard-blocks cross-origin dev requests (HMR WebSocket, Server Actions) from\n// origins missing here.\nconst PLATFORM_DEV_ORIGINS = [\n \"localhost:*\",\n \"*.localhost:*\",\n \"*.lvh.me:*\",\n \"*.daytonaproxy01.net\",\n \"*.preview.reploapi.com\",\n \"*.preview-staging.reploapi.com\",\n];\n\nconst PLATFORM_SERVER_ACTION_ORIGINS = [\n \"localhost:*\",\n \"*.localhost:*\",\n \"*.lvh.me:*\",\n \"*.cloudflare-agent-coordinator.replo.workers.dev\",\n \"*.preview.reploapi.com\",\n \"*.preview-staging.reploapi.com\",\n];\n\nconst DEFAULT_PAGE_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"];\n// Routed only by the sandbox dev server: site-component previews and page drafts.\nconst DEVELOPMENT_ONLY_PAGE_EXTENSIONS = [\"dev.jsx\", \"dev.tsx\"];\n// Routed only by publish builds: the live copy of every page.\nconst BUILD_ONLY_PAGE_EXTENSIONS = [\"published.tsx\"];\nconst PUBLISH_TSCONFIG_FILENAME = \"tsconfig.publish.json\";\n\n// Pair routing is a platform invariant, not an editor nicety: without it a\n// build silently drops every page.published.tsx, so the site ships missing\n// routes. A site's own extensions are kept, but platform ones are filtered out\n// of the input and re-prepended so a site can never drop pair routing.\n// Behaviorally identical to @replohq/sandbox-runtime's wrapper, which\n// starter-scaffolded sites use instead of this function.\nfunction resolvePageExtensions(configuredExtensions: string[] | undefined) {\n const baseExtensions = (\n configuredExtensions ?? DEFAULT_PAGE_EXTENSIONS\n ).filter((extension) => {\n return (\n !DEVELOPMENT_ONLY_PAGE_EXTENSIONS.includes(extension) &&\n !BUILD_ONLY_PAGE_EXTENSIONS.includes(extension)\n );\n });\n\n return process.env.BUILD_ENV === \"build\"\n ? [...BUILD_ONLY_PAGE_EXTENSIONS, ...baseExtensions]\n : [...DEVELOPMENT_ONLY_PAGE_EXTENSIONS, ...baseExtensions];\n}\n\n// Drafts are excluded from the publish typecheck so unfinished pages never\n// block a publish; live files stay checked. Overrides the site's own\n// tsconfigPath during publish builds when the publish tsconfig is present.\nfunction resolvePublishTypescriptConfig(configured: NextConfig[\"typescript\"]) {\n if (process.env.BUILD_ENV !== \"build\") {\n return configured;\n }\n\n const tsconfigPath = path.join(process.cwd(), PUBLISH_TSCONFIG_FILENAME);\n return existsSync(tsconfigPath)\n ? { ...configured, tsconfigPath: PUBLISH_TSCONFIG_FILENAME }\n : configured;\n}\n\n// The canonical Next.js runtime contract shared by every agent-built site.\n// Sites re-export `default` from here through a one-line `next.config.ts` shim,\n// so the platform wiring (sandbox dist dirs, Turbopack root, preview origins,\n// Cloudflare image loader) lives in exactly one place instead of being copied\n// into each template.\n//\n// `overrides` is a per-site customization surface, but it must not be able to\n// silently amputate platform wiring. A plain `...overrides` spread is a shallow\n// merge: a site that sets any nested key (e.g. `experimental.typedRoutes`)\n// would replace the whole `experimental`/`images` block and drop platform\n// defaults like the build-worker OOM guard or the Cloudflare image loader. So\n// load-bearing keys are re-asserted after the spread and the nested blocks are\n// deep-merged: a site can add keys, but platform invariants always win and\n// platform origin lists are preserved (site entries are appended, not swapped).\nexport function siteConfig(overrides: NextConfig = {}): NextConfig {\n const isBuild = process.env.BUILD_ENV === \"build\";\n const devRoot = process.env.IS_REPLO_SANDBOX\n ? \"/workspace/dev\"\n : process.cwd();\n const {\n turbopack: overrideTurbopack,\n images: overrideImages,\n experimental: overrideExperimental,\n allowedDevOrigins: overrideDevOrigins,\n pageExtensions: overridePageExtensions,\n typescript: overrideTypescript,\n ...restOverrides\n } = overrides;\n\n const { serverActions: overrideServerActions, ...restOverrideExperimental } =\n overrideExperimental ?? {};\n\n return {\n // Site-overridable defaults.\n reactStrictMode: true,\n devIndicators: false,\n ...restOverrides,\n\n // Platform invariants \u2014 re-asserted after the spread so a site override\n // can never break sandbox builds, publish, or the dev server.\n output: \"standalone\",\n distDir: isBuild ? \".next\" : \".next-dev\",\n pageExtensions: resolvePageExtensions(overridePageExtensions),\n typescript: resolvePublishTypescriptConfig(overrideTypescript),\n // NOTE (Cole, 2026-04-30, REPL-26637): The publish tool patches\n // required-server-files.json to clear this value before OpenNext bundles,\n // since \"/\" makes esbuild emit absolute-path requires that break in Workers.\n // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Leave outputFileTracingRoot\n // unset outside builds because Next 15.5+ otherwise forces turbopack.root to\n // \"/\" and makes the dev watcher retain whole-filesystem state.\n outputFileTracingRoot: isBuild ? \"/\" : undefined,\n // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Match build tracing at publish\n // time; keep dev's watcher on the user app tree.\n turbopack: {\n ...overrideTurbopack,\n root: isBuild ? \"/\" : devRoot,\n },\n // @replohq/sdk ships as raw source with zero workspace deps, so we can't pull\n // in lodash-es `uniq` here \u2014 dedupe inline via a Set instead.\n allowedDevOrigins: Array.from(\n new Set([...(overrideDevOrigins ?? []), ...PLATFORM_DEV_ORIGINS]),\n ),\n images: {\n ...overrideImages,\n loader: \"custom\",\n loaderFile: \"./image-loader.ts\",\n remotePatterns: overrideImages?.remotePatterns ?? [\n {\n protocol: \"https\",\n hostname: \"**\",\n },\n ],\n },\n experimental: {\n ...restOverrideExperimental,\n // NOTE (Cole, 2026-06-18, REPL-28180): Next sizes its build worker pool\n // off os.cpus().length = host cores (~64) inside a cgroup-limited sandbox,\n // not the 2 the container actually has \u2014 a worker swarm that OOMs the\n // 4 GiB box. availableParallelism() is cgroup-aware. Gated to prod build.\n cpus: isBuild ? os.availableParallelism() : undefined,\n serverActions: {\n ...overrideServerActions,\n allowedOrigins: Array.from(\n new Set([\n ...(overrideServerActions?.allowedOrigins ?? []),\n ...PLATFORM_SERVER_ACTION_ORIGINS,\n ]),\n ),\n },\n },\n };\n}\n\nconst nextConfig: NextConfig = siteConfig();\n\nexport default nextConfig;\n"],
5
- "mappings": "AAAA,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AAOjB,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,iCAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,0BAA0B,CAAC,OAAO,MAAM,OAAO,IAAI;AAEzD,MAAM,mCAAmC,CAAC,WAAW,SAAS;AAE9D,MAAM,6BAA6B,CAAC,eAAe;AACnD,MAAM,4BAA4B;AAQlC,SAAS,sBAAsB,sBAA4C;AACzE,QAAM,kBACJ,wBAAwB,yBACxB,OAAO,CAAC,cAAc;AACtB,WACE,CAAC,iCAAiC,SAAS,SAAS,KACpD,CAAC,2BAA2B,SAAS,SAAS;AAAA,EAElD,CAAC;AAED,SAAO,QAAQ,IAAI,cAAc,UAC7B,CAAC,GAAG,4BAA4B,GAAG,cAAc,IACjD,CAAC,GAAG,kCAAkC,GAAG,cAAc;AAC7D;AAKA,SAAS,+BAA+B,YAAsC;AAC5E,MAAI,QAAQ,IAAI,cAAc,SAAS;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,KAAK,KAAK,QAAQ,IAAI,GAAG,yBAAyB;AACvE,SAAO,WAAW,YAAY,IAC1B,EAAE,GAAG,YAAY,cAAc,0BAA0B,IACzD;AACN;AAgBO,SAAS,WAAW,YAAwB,CAAC,GAAe;AACjE,QAAM,UAAU,QAAQ,IAAI,cAAc;AAC1C,QAAM,UAAU,QAAQ,IAAI,mBACxB,mBACA,QAAQ,IAAI;AAChB,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,EAAE,eAAe,uBAAuB,GAAG,yBAAyB,IACxE,wBAAwB,CAAC;AAE3B,SAAO;AAAA;AAAA,IAEL,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,GAAG;AAAA;AAAA;AAAA,IAIH,QAAQ;AAAA,IACR,SAAS,UAAU,UAAU;AAAA,IAC7B,gBAAgB,sBAAsB,sBAAsB;AAAA,IAC5D,YAAY,+BAA+B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7D,uBAAuB,UAAU,MAAM;AAAA;AAAA;AAAA,IAGvC,WAAW;AAAA,MACT,GAAG;AAAA,MACH,MAAM,UAAU,MAAM;AAAA,IACxB;AAAA;AAAA;AAAA,IAGA,mBAAmB,MAAM;AAAA,MACvB,oBAAI,IAAI,CAAC,GAAI,sBAAsB,CAAC,GAAI,GAAG,oBAAoB,CAAC;AAAA,IAClE;AAAA,IACA,QAAQ;AAAA,MACN,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB,gBAAgB,kBAAkB;AAAA,QAChD;AAAA,UACE,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,MAKH,MAAM,UAAU,GAAG,qBAAqB,IAAI;AAAA,MAC5C,eAAe;AAAA,QACb,GAAG;AAAA,QACH,gBAAgB,MAAM;AAAA,UACpB,oBAAI,IAAI;AAAA,YACN,GAAI,uBAAuB,kBAAkB,CAAC;AAAA,YAC9C,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,aAAyB,WAAW;AAE1C,IAAO,iBAAQ;",
4
+ "sourcesContent": ["import { existsSync } from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport type { NextConfig } from \"next\";\n\n// Origins browsers load sandbox previews from \u2014 PREVIEW_HOSTNAME in the\n// coordinator's wrangler.jsonc plus Daytona's native preview domain. Next 16\n// hard-blocks cross-origin dev requests (HMR WebSocket, Server Actions) from\n// origins missing here.\nconst PLATFORM_DEV_ORIGINS = [\n \"localhost:*\",\n \"*.localhost:*\",\n \"*.lvh.me:*\",\n \"*.daytonaproxy01.net\",\n \"*.preview.reploapi.com\",\n \"*.preview-staging.reploapi.com\",\n];\n\nconst PLATFORM_SERVER_ACTION_ORIGINS = [\n \"localhost:*\",\n \"*.localhost:*\",\n \"*.lvh.me:*\",\n \"*.cloudflare-agent-coordinator.replo.workers.dev\",\n \"*.preview.reploapi.com\",\n \"*.preview-staging.reploapi.com\",\n];\n\nconst DEFAULT_PAGE_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"];\n// Routed only by the sandbox dev server: site-component previews and page drafts.\nconst DEVELOPMENT_ONLY_PAGE_EXTENSIONS = [\"dev.jsx\", \"dev.tsx\"];\n// Routed only by publish builds: the live copy of every page.\nconst BUILD_ONLY_PAGE_EXTENSIONS = [\"published.tsx\"];\nconst PUBLISH_TSCONFIG_FILENAME = \"tsconfig.publish.json\";\n\n// Pair routing is a platform invariant, not an editor nicety: without it a\n// build silently drops every page.published.tsx, so the site ships missing\n// routes. A site's own extensions are kept, but platform ones are filtered out\n// of the input and re-prepended so a site can never drop pair routing.\n// Behaviorally identical to @replohq/sandbox-runtime's wrapper, which\n// starter-scaffolded sites use instead of this function.\nfunction resolvePageExtensions(configuredExtensions: string[] | undefined) {\n const baseExtensions = (\n configuredExtensions ?? DEFAULT_PAGE_EXTENSIONS\n ).filter((extension) => {\n return (\n !DEVELOPMENT_ONLY_PAGE_EXTENSIONS.includes(extension) &&\n !BUILD_ONLY_PAGE_EXTENSIONS.includes(extension)\n );\n });\n\n return process.env.BUILD_ENV === \"build\"\n ? [...BUILD_ONLY_PAGE_EXTENSIONS, ...baseExtensions]\n : [...DEVELOPMENT_ONLY_PAGE_EXTENSIONS, ...baseExtensions];\n}\n\n// Drafts are excluded from the publish typecheck so unfinished pages never\n// block a publish; live files stay checked. Overrides the site's own\n// tsconfigPath during publish builds when the publish tsconfig is present.\nfunction resolvePublishTypescriptConfig(configured: NextConfig[\"typescript\"]) {\n if (process.env.BUILD_ENV !== \"build\") {\n return configured;\n }\n\n const tsconfigPath = path.join(process.cwd(), PUBLISH_TSCONFIG_FILENAME);\n return existsSync(tsconfigPath)\n ? { ...configured, tsconfigPath: PUBLISH_TSCONFIG_FILENAME }\n : configured;\n}\n\n/**\n * Builds the site's `next.config.ts`, layering your options over Replo's\n * platform defaults (image loader, preview origins, build settings). Add keys\n * freely: nested blocks are deep-merged, and platform wiring always wins, so\n * setting one nested option never drops the rest of the block.\n *\n * Export the result as the default from `next.config.ts`. A site that needs no\n * customization can re-export this module's own default instead.\n *\n * @param overrides Next.js config options to layer on top of the defaults.\n * @returns The merged Next.js config.\n * @example\n * ```ts\n * import { siteConfig } from \"@replohq/sdk/next/config\";\n *\n * export default siteConfig({ experimental: { typedRoutes: true } });\n * ```\n */\n// The canonical Next.js runtime contract shared by every agent-built site.\n// Sites re-export `default` from here through a one-line `next.config.ts` shim,\n// so the platform wiring (sandbox dist dirs, Turbopack root, preview origins,\n// Cloudflare image loader) lives in exactly one place instead of being copied\n// into each template.\n//\n// `overrides` is a per-site customization surface, but it must not be able to\n// silently amputate platform wiring. A plain `...overrides` spread is a shallow\n// merge: a site that sets any nested key (e.g. `experimental.typedRoutes`)\n// would replace the whole `experimental`/`images` block and drop platform\n// defaults like the build-worker OOM guard or the Cloudflare image loader. So\n// load-bearing keys are re-asserted after the spread and the nested blocks are\n// deep-merged: a site can add keys, but platform invariants always win and\n// platform origin lists are preserved (site entries are appended, not swapped).\nexport function siteConfig(overrides: NextConfig = {}): NextConfig {\n const isBuild = process.env.BUILD_ENV === \"build\";\n const devRoot = process.env.IS_REPLO_SANDBOX\n ? \"/workspace/dev\"\n : process.cwd();\n const {\n turbopack: overrideTurbopack,\n images: overrideImages,\n experimental: overrideExperimental,\n allowedDevOrigins: overrideDevOrigins,\n pageExtensions: overridePageExtensions,\n typescript: overrideTypescript,\n ...restOverrides\n } = overrides;\n\n const { serverActions: overrideServerActions, ...restOverrideExperimental } =\n overrideExperimental ?? {};\n\n return {\n // Site-overridable defaults.\n reactStrictMode: true,\n devIndicators: false,\n ...restOverrides,\n\n // Platform invariants \u2014 re-asserted after the spread so a site override\n // can never break sandbox builds, publish, or the dev server.\n output: \"standalone\",\n distDir: isBuild ? \".next\" : \".next-dev\",\n pageExtensions: resolvePageExtensions(overridePageExtensions),\n typescript: resolvePublishTypescriptConfig(overrideTypescript),\n // NOTE (Cole, 2026-04-30, REPL-26637): The publish tool patches\n // required-server-files.json to clear this value before OpenNext bundles,\n // since \"/\" makes esbuild emit absolute-path requires that break in Workers.\n // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Leave outputFileTracingRoot\n // unset outside builds because Next 15.5+ otherwise forces turbopack.root to\n // \"/\" and makes the dev watcher retain whole-filesystem state.\n outputFileTracingRoot: isBuild ? \"/\" : undefined,\n // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Match build tracing at publish\n // time; keep dev's watcher on the user app tree.\n turbopack: {\n ...overrideTurbopack,\n root: isBuild ? \"/\" : devRoot,\n },\n // @replohq/sdk ships as raw source with zero workspace deps, so we can't pull\n // in lodash-es `uniq` here \u2014 dedupe inline via a Set instead.\n allowedDevOrigins: Array.from(\n new Set([...(overrideDevOrigins ?? []), ...PLATFORM_DEV_ORIGINS]),\n ),\n images: {\n ...overrideImages,\n loader: \"custom\",\n loaderFile: \"./image-loader.ts\",\n remotePatterns: overrideImages?.remotePatterns ?? [\n {\n protocol: \"https\",\n hostname: \"**\",\n },\n ],\n },\n experimental: {\n ...restOverrideExperimental,\n // NOTE (Cole, 2026-06-18, REPL-28180): Next sizes its build worker pool\n // off os.cpus().length = host cores (~64) inside a cgroup-limited sandbox,\n // not the 2 the container actually has \u2014 a worker swarm that OOMs the\n // 4 GiB box. availableParallelism() is cgroup-aware. Gated to prod build.\n cpus: isBuild ? os.availableParallelism() : undefined,\n serverActions: {\n ...overrideServerActions,\n allowedOrigins: Array.from(\n new Set([\n ...(overrideServerActions?.allowedOrigins ?? []),\n ...PLATFORM_SERVER_ACTION_ORIGINS,\n ]),\n ),\n },\n },\n };\n}\n\nconst nextConfig: NextConfig = siteConfig();\n\nexport default nextConfig;\n"],
5
+ "mappings": "AAAA,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AAOjB,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,iCAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,0BAA0B,CAAC,OAAO,MAAM,OAAO,IAAI;AAEzD,MAAM,mCAAmC,CAAC,WAAW,SAAS;AAE9D,MAAM,6BAA6B,CAAC,eAAe;AACnD,MAAM,4BAA4B;AAQlC,SAAS,sBAAsB,sBAA4C;AACzE,QAAM,kBACJ,wBAAwB,yBACxB,OAAO,CAAC,cAAc;AACtB,WACE,CAAC,iCAAiC,SAAS,SAAS,KACpD,CAAC,2BAA2B,SAAS,SAAS;AAAA,EAElD,CAAC;AAED,SAAO,QAAQ,IAAI,cAAc,UAC7B,CAAC,GAAG,4BAA4B,GAAG,cAAc,IACjD,CAAC,GAAG,kCAAkC,GAAG,cAAc;AAC7D;AAKA,SAAS,+BAA+B,YAAsC;AAC5E,MAAI,QAAQ,IAAI,cAAc,SAAS;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,KAAK,KAAK,QAAQ,IAAI,GAAG,yBAAyB;AACvE,SAAO,WAAW,YAAY,IAC1B,EAAE,GAAG,YAAY,cAAc,0BAA0B,IACzD;AACN;AAkCO,SAAS,WAAW,YAAwB,CAAC,GAAe;AACjE,QAAM,UAAU,QAAQ,IAAI,cAAc;AAC1C,QAAM,UAAU,QAAQ,IAAI,mBACxB,mBACA,QAAQ,IAAI;AAChB,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,EAAE,eAAe,uBAAuB,GAAG,yBAAyB,IACxE,wBAAwB,CAAC;AAE3B,SAAO;AAAA;AAAA,IAEL,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,GAAG;AAAA;AAAA;AAAA,IAIH,QAAQ;AAAA,IACR,SAAS,UAAU,UAAU;AAAA,IAC7B,gBAAgB,sBAAsB,sBAAsB;AAAA,IAC5D,YAAY,+BAA+B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7D,uBAAuB,UAAU,MAAM;AAAA;AAAA;AAAA,IAGvC,WAAW;AAAA,MACT,GAAG;AAAA,MACH,MAAM,UAAU,MAAM;AAAA,IACxB;AAAA;AAAA;AAAA,IAGA,mBAAmB,MAAM;AAAA,MACvB,oBAAI,IAAI,CAAC,GAAI,sBAAsB,CAAC,GAAI,GAAG,oBAAoB,CAAC;AAAA,IAClE;AAAA,IACA,QAAQ;AAAA,MACN,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB,gBAAgB,kBAAkB;AAAA,QAChD;AAAA,UACE,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,MAKH,MAAM,UAAU,GAAG,qBAAqB,IAAI;AAAA,MAC5C,eAAe;AAAA,QACb,GAAG;AAAA,QACH,gBAAgB,MAAM;AAAA,UACpB,oBAAI,IAAI;AAAA,YACN,GAAI,uBAAuB,kBAAkB,CAAC;AAAA,YAC9C,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,aAAyB,WAAW;AAE1C,IAAO,iBAAQ;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sdk",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sdk",
6
- "version": "1.5.0",
6
+ "version": "1.6.0",
7
7
  "branch": "HEAD",
8
- "commit": "26358ebb6719c706ba541c3b75687181c732615c",
9
- "builtAt": "2026-09-09T19:22:13.298Z"
8
+ "commit": "4864322a9ff1f3dd385fee9bc0010f4535520cbb",
9
+ "builtAt": "2026-09-10T21:47:40.227Z"
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",
@@ -1 +1,20 @@
1
+ /**
2
+ * Root provider for a Replo site. Mount it once in `app/layout.tsx`, wrapping
3
+ * the whole app. It sets up the React Query client every data loader reads
4
+ * from, the analytics layer, and cart state, so `useCart`, `useAnalytics`, and
5
+ * the loader components only work beneath it.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * export default function RootLayout({ children }: React.PropsWithChildren) {
10
+ * return (
11
+ * <html lang="en">
12
+ * <body>
13
+ * <ReploProvider>{children}</ReploProvider>
14
+ * </body>
15
+ * </html>
16
+ * );
17
+ * }
18
+ * ```
19
+ */
1
20
  export declare function ReploProvider({ children }: React.PropsWithChildren): Promise<import("react/jsx-runtime").JSX.Element>;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../providers/replo-provider.tsx"],
4
- "sourcesContent": ["import type { CheckoutProvider } from \"../lib/integration-utils\";\n\nimport { AnalyticsProvider } from \"../analytics/analytics-provider\";\nimport { ReploFirstPartyPixel } from \"../analytics/replo-first-party-pixel\";\nimport { CartLoader } from \"../cart/cart-loader\";\nimport { getCheckoutProvider } from \"../lib/integration-utils\";\nimport { QueryProvider } from \"./query-provider\";\n\nexport async function ReploProvider({ children }: React.PropsWithChildren) {\n // Server-resolved so the analytics layer can suppress checkout-funnel events\n // that Shopify's hosted checkout already reports. Defaults to \"none\" (events\n // fire) if the env can't be read, preserving prior behavior.\n let checkoutProvider: CheckoutProvider = \"none\";\n try {\n checkoutProvider = await getCheckoutProvider();\n } catch {\n checkoutProvider = \"none\";\n }\n\n return (\n <QueryProvider>\n <AnalyticsProvider checkoutProvider={checkoutProvider}>\n <ReploFirstPartyPixel />\n <CartLoader>{children}</CartLoader>\n </AnalyticsProvider>\n </QueryProvider>\n );\n}\n"],
5
- "mappings": "AAqBM,SACE,KADF;AAnBN,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAE9B,eAAsB,cAAc,EAAE,SAAS,GAA4B;AAIzE,MAAI,mBAAqC;AACzC,MAAI;AACF,uBAAmB,MAAM,oBAAoB;AAAA,EAC/C,QAAQ;AACN,uBAAmB;AAAA,EACrB;AAEA,SACE,oBAAC,iBACC,+BAAC,qBAAkB,kBACjB;AAAA,wBAAC,wBAAqB;AAAA,IACtB,oBAAC,cAAY,UAAS;AAAA,KACxB,GACF;AAEJ;",
4
+ "sourcesContent": ["import type { CheckoutProvider } from \"../lib/integration-utils\";\n\nimport { AnalyticsProvider } from \"../analytics/analytics-provider\";\nimport { ReploFirstPartyPixel } from \"../analytics/replo-first-party-pixel\";\nimport { CartLoader } from \"../cart/cart-loader\";\nimport { getCheckoutProvider } from \"../lib/integration-utils\";\nimport { QueryProvider } from \"./query-provider\";\n\n/**\n * Root provider for a Replo site. Mount it once in `app/layout.tsx`, wrapping\n * the whole app. It sets up the React Query client every data loader reads\n * from, the analytics layer, and cart state, so `useCart`, `useAnalytics`, and\n * the loader components only work beneath it.\n *\n * @example\n * ```tsx\n * export default function RootLayout({ children }: React.PropsWithChildren) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <ReploProvider>{children}</ReploProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport async function ReploProvider({ children }: React.PropsWithChildren) {\n // Server-resolved so the analytics layer can suppress checkout-funnel events\n // that Shopify's hosted checkout already reports. Defaults to \"none\" (events\n // fire) if the env can't be read, preserving prior behavior.\n let checkoutProvider: CheckoutProvider = \"none\";\n try {\n checkoutProvider = await getCheckoutProvider();\n } catch {\n checkoutProvider = \"none\";\n }\n\n return (\n <QueryProvider>\n <AnalyticsProvider checkoutProvider={checkoutProvider}>\n <ReploFirstPartyPixel />\n <CartLoader>{children}</CartLoader>\n </AnalyticsProvider>\n </QueryProvider>\n );\n}\n"],
5
+ "mappings": "AAwCM,SACE,KADF;AAtCN,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAqB9B,eAAsB,cAAc,EAAE,SAAS,GAA4B;AAIzE,MAAI,mBAAqC;AACzC,MAAI;AACF,uBAAmB,MAAM,oBAAoB;AAAA,EAC/C,QAAQ;AACN,uBAAmB;AAAA,EACrB;AAEA,SACE,oBAAC,iBACC,+BAAC,qBAAkB,kBACjB;AAAA,wBAAC,wBAAqB;AAAA,IACtB,oBAAC,cAAY,UAAS;AAAA,KACxB,GACF;AAEJ;",
6
6
  "names": []
7
7
  }