@replohq/sdk 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_vendor/schemas/loaderKeys.mjs +1 -0
- package/analytics/analytics-provider.d.ts +2 -0
- package/analytics/analytics-provider.js +38 -8
- package/analytics/analytics-sink.d.ts +9 -0
- package/analytics/combine-sinks.js +2 -1
- package/analytics/sinks/intelligems-sink.d.ts +29 -0
- package/analytics/sinks/intelligems-sink.js +68 -0
- package/cart/buy-now-action.d.ts +4 -0
- package/cart/buy-now-action.js +2 -1
- package/cart/cart-actions.d.ts +4 -0
- package/cart/cart-actions.js +2 -0
- package/cart/cart-provider.d.ts +2 -0
- package/cart/cart-provider.js +1 -0
- package/cart/gateways/cart-gateway.d.ts +4 -0
- package/cart/gateways/resolver-cart-gateway.js +2 -0
- package/cart/hooks/use-buy-now.d.ts +5 -0
- package/cart/hooks/use-buy-now.js +1 -0
- package/gateways/canopy-api.d.ts +4 -0
- package/gateways/canopy-api.js +1 -0
- package/lib/buildMetadata.js +3 -3
- package/loaders/loader-keys.d.ts +1 -0
- package/loaders/loader-keys.js +1 -0
- package/loaders/loader-schemas.d.ts +5 -0
- package/loaders/loader-schemas.js +9 -0
- package/loaders/shopify-integration-details-loader.d.ts +9 -0
- package/loaders/shopify-integration-details-loader.js +33 -0
- package/next/open-next.js +14 -1
- package/package.json +12 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../../chunk-UJCSKKID.mjs';
|
|
2
2
|
|
|
3
3
|
var DATA_LOADER_KEYS = {
|
|
4
|
+
SHOPIFY_INTEGRATION_DETAILS: "shopify_storefront.integration_details",
|
|
4
5
|
SHOPIFY_PRODUCT: "shopify_storefront.product",
|
|
5
6
|
SHOPIFY_COLLECTION: "shopify_storefront.collection",
|
|
6
7
|
SHOPIFY_COLLECTION_PRODUCTS: "shopify_storefront.collection_products",
|
|
@@ -4,6 +4,8 @@ import type { AnalyticsSink } from "./analytics-sink";
|
|
|
4
4
|
export declare function AnalyticsProvider({ children, checkoutProvider, }: React.PropsWithChildren<{
|
|
5
5
|
checkoutProvider?: CheckoutProvider;
|
|
6
6
|
}>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
/** Register one stable, consent-aware sink beneath ReploProvider. */
|
|
8
|
+
export declare function useAnalyticsSink(sink: AnalyticsSink): void;
|
|
7
9
|
/**
|
|
8
10
|
* Returns the AnalyticsSink from the nearest AnalyticsProvider.
|
|
9
11
|
* Throws if used outside of an AnalyticsProvider.
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useMemo,
|
|
9
|
+
useRef,
|
|
10
|
+
useState
|
|
11
|
+
} from "react";
|
|
4
12
|
import { useConsent } from "../consent/consent-store";
|
|
5
13
|
import { useRegisteredScripts } from "../consent/script-registration-store";
|
|
6
14
|
import { combineSinks } from "./combine-sinks";
|
|
@@ -13,9 +21,18 @@ function AnalyticsProvider({
|
|
|
13
21
|
}) {
|
|
14
22
|
const consent = useConsent();
|
|
15
23
|
const registeredScripts = useRegisteredScripts();
|
|
24
|
+
const [additionalSinks, setAdditionalSinks] = useState([]);
|
|
25
|
+
const registerSink = useCallback((sink) => {
|
|
26
|
+
setAdditionalSinks((current) => [...current, sink]);
|
|
27
|
+
return () => {
|
|
28
|
+
setAdditionalSinks((current) => {
|
|
29
|
+
return current.filter((registered) => registered !== sink);
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
}, []);
|
|
16
33
|
const analytics = useMemo(() => {
|
|
17
|
-
return combineSinks(
|
|
18
|
-
getAnalyticsSinks({
|
|
34
|
+
return combineSinks([
|
|
35
|
+
...getAnalyticsSinks({
|
|
19
36
|
consent: {
|
|
20
37
|
cmp: consent.cmp,
|
|
21
38
|
mode: consent.mode,
|
|
@@ -24,15 +41,17 @@ function AnalyticsProvider({
|
|
|
24
41
|
},
|
|
25
42
|
registeredScripts,
|
|
26
43
|
checkoutProvider
|
|
27
|
-
})
|
|
28
|
-
|
|
44
|
+
}),
|
|
45
|
+
...additionalSinks
|
|
46
|
+
]);
|
|
29
47
|
}, [
|
|
30
48
|
consent.cmp,
|
|
31
49
|
consent.mode,
|
|
32
50
|
consent.categories,
|
|
33
51
|
consent.decidedAt,
|
|
34
52
|
registeredScripts,
|
|
35
|
-
checkoutProvider
|
|
53
|
+
checkoutProvider,
|
|
54
|
+
additionalSinks
|
|
36
55
|
]);
|
|
37
56
|
const analyticsRef = useRef(analytics);
|
|
38
57
|
analyticsRef.current = analytics;
|
|
@@ -51,7 +70,17 @@ function AnalyticsProvider({
|
|
|
51
70
|
navigationTracker.current?.cleanup();
|
|
52
71
|
};
|
|
53
72
|
}, []);
|
|
54
|
-
return /* @__PURE__ */ jsx(AnalyticsContext.Provider, { value: { analytics }, children });
|
|
73
|
+
return /* @__PURE__ */ jsx(AnalyticsContext.Provider, { value: { analytics, registerSink }, children });
|
|
74
|
+
}
|
|
75
|
+
function useAnalyticsSink(sink) {
|
|
76
|
+
const context = useContext(AnalyticsContext);
|
|
77
|
+
if (!context) {
|
|
78
|
+
throw new AnalyticsContextError({
|
|
79
|
+
message: "useAnalyticsSink must be used within <AnalyticsProvider>"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const registerSink = context.registerSink;
|
|
83
|
+
useEffect(() => registerSink(sink), [registerSink, sink]);
|
|
55
84
|
}
|
|
56
85
|
class AnalyticsContextError extends Error {
|
|
57
86
|
constructor({ message }) {
|
|
@@ -74,5 +103,6 @@ function useAnalyticsOptional() {
|
|
|
74
103
|
export {
|
|
75
104
|
AnalyticsProvider,
|
|
76
105
|
useAnalytics,
|
|
77
|
-
useAnalyticsOptional
|
|
106
|
+
useAnalyticsOptional,
|
|
107
|
+
useAnalyticsSink
|
|
78
108
|
};
|
|
@@ -13,7 +13,16 @@ export type PurchasePayload = {
|
|
|
13
13
|
currency: string;
|
|
14
14
|
data: Record<string, any>;
|
|
15
15
|
};
|
|
16
|
+
export type AnalyticsProperty = string | number | boolean | null | AnalyticsProperty[] | {
|
|
17
|
+
[key: string]: AnalyticsProperty;
|
|
18
|
+
};
|
|
19
|
+
export interface CustomEventPayload {
|
|
20
|
+
event: string;
|
|
21
|
+
properties?: Record<string, AnalyticsProperty>;
|
|
22
|
+
}
|
|
16
23
|
export interface AnalyticsSink {
|
|
24
|
+
/** Explicit business goals; sinks without custom-event support may omit this. */
|
|
25
|
+
customEvent?(payload: CustomEventPayload): Promise<void>;
|
|
17
26
|
pageView(metadata?: PageMetadata): Promise<void>;
|
|
18
27
|
purchase(payload: PurchasePayload): Promise<void>;
|
|
19
28
|
click(payload: DataPayload): Promise<void>;
|
|
@@ -12,7 +12,7 @@ function combineSinks(sinks) {
|
|
|
12
12
|
sinks.map(async (sink) => {
|
|
13
13
|
try {
|
|
14
14
|
const sinkMethod = sink[method];
|
|
15
|
-
await sinkMethod
|
|
15
|
+
await sinkMethod?.apply(sink, args);
|
|
16
16
|
} catch {
|
|
17
17
|
if (typeof window !== "undefined") {
|
|
18
18
|
console.warn("[analytics] sink error", { method });
|
|
@@ -22,6 +22,7 @@ function combineSinks(sinks) {
|
|
|
22
22
|
);
|
|
23
23
|
};
|
|
24
24
|
return {
|
|
25
|
+
customEvent: (...args) => broadcast("customEvent", ...args),
|
|
25
26
|
pageView: (...args) => broadcast("pageView", ...args),
|
|
26
27
|
purchase: (...args) => broadcast("purchase", ...args),
|
|
27
28
|
click: (...args) => broadcast("click", ...args),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AnalyticsSink, CustomEventPayload, DataPayload, PurchasePayload } from "../analytics-sink";
|
|
2
|
+
import type { PageMetadata } from "../utils/navigation-tracker";
|
|
3
|
+
export type IntelligemsEventMappings = {
|
|
4
|
+
[Method in Exclude<keyof AnalyticsSink, "customEvent">]?: (...args: Parameters<AnalyticsSink[Method]>) => CustomEventPayload | null;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Sends explicitly selected custom goals through the installed Intelligems SDK.
|
|
8
|
+
* Native page views, experiment assignment, and order attribution remain owned
|
|
9
|
+
* by useIgTrack and Shopify; duplicating them as custom events changes reports.
|
|
10
|
+
*/
|
|
11
|
+
export declare class IntelligemsSink implements AnalyticsSink {
|
|
12
|
+
private readonly options;
|
|
13
|
+
constructor(options: {
|
|
14
|
+
/** Read live SDK readiness; do not accept events before assignment resolves. */
|
|
15
|
+
isReady: () => boolean;
|
|
16
|
+
events?: IntelligemsEventMappings;
|
|
17
|
+
});
|
|
18
|
+
customEvent(payload: CustomEventPayload): Promise<void>;
|
|
19
|
+
private send;
|
|
20
|
+
pageView(metadata?: PageMetadata): Promise<void>;
|
|
21
|
+
purchase(payload: PurchasePayload): Promise<void>;
|
|
22
|
+
click(payload: DataPayload): Promise<void>;
|
|
23
|
+
productViewed(payload: DataPayload): Promise<void>;
|
|
24
|
+
addToCart(payload: DataPayload): Promise<void>;
|
|
25
|
+
removeFromCart(payload: DataPayload): Promise<void>;
|
|
26
|
+
viewCart(payload: DataPayload): Promise<void>;
|
|
27
|
+
startCheckout(payload: DataPayload): Promise<void>;
|
|
28
|
+
viewCollection(payload: DataPayload): Promise<void>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { consentStore, isConsentAllowed } from "../../consent/consent-store";
|
|
3
|
+
class IntelligemsSink {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
async customEvent(payload) {
|
|
8
|
+
if (typeof window === "undefined" || !this.options.isReady()) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!isConsentAllowed({
|
|
12
|
+
state: consentStore.getSnapshot(),
|
|
13
|
+
requiredConsent: ["analytics"]
|
|
14
|
+
})) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!payload.event.trim() || /[,']/.test(payload.event) || payload.event !== payload.event.trim()) {
|
|
18
|
+
throw new IntelligemsEventNameError(
|
|
19
|
+
"Intelligems event names must be nonempty, trimmed, and contain no commas or single quotes"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (!("igEvents" in window)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const transport = window.igEvents;
|
|
26
|
+
if (!transport || typeof transport !== "object" || Array.isArray(transport) || !("push" in transport) || typeof transport.push !== "function") {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await transport.push(payload);
|
|
30
|
+
}
|
|
31
|
+
async send(payload) {
|
|
32
|
+
if (payload) {
|
|
33
|
+
await this.customEvent(payload);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async pageView(metadata) {
|
|
37
|
+
await this.send(this.options.events?.pageView?.(metadata));
|
|
38
|
+
}
|
|
39
|
+
async purchase(payload) {
|
|
40
|
+
await this.send(this.options.events?.purchase?.(payload));
|
|
41
|
+
}
|
|
42
|
+
async click(payload) {
|
|
43
|
+
await this.send(this.options.events?.click?.(payload));
|
|
44
|
+
}
|
|
45
|
+
async productViewed(payload) {
|
|
46
|
+
await this.send(this.options.events?.productViewed?.(payload));
|
|
47
|
+
}
|
|
48
|
+
async addToCart(payload) {
|
|
49
|
+
await this.send(this.options.events?.addToCart?.(payload));
|
|
50
|
+
}
|
|
51
|
+
async removeFromCart(payload) {
|
|
52
|
+
await this.send(this.options.events?.removeFromCart?.(payload));
|
|
53
|
+
}
|
|
54
|
+
async viewCart(payload) {
|
|
55
|
+
await this.send(this.options.events?.viewCart?.(payload));
|
|
56
|
+
}
|
|
57
|
+
async startCheckout(payload) {
|
|
58
|
+
await this.send(this.options.events?.startCheckout?.(payload));
|
|
59
|
+
}
|
|
60
|
+
async viewCollection(payload) {
|
|
61
|
+
await this.send(this.options.events?.viewCollection?.(payload));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
class IntelligemsEventNameError extends Error {
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
IntelligemsSink
|
|
68
|
+
};
|
package/cart/buy-now-action.d.ts
CHANGED
package/cart/buy-now-action.js
CHANGED
|
@@ -122,7 +122,8 @@ async function buyNowWithRecoveryAction(input) {
|
|
|
122
122
|
lines: cartLines,
|
|
123
123
|
skipStoringCart: true,
|
|
124
124
|
country: input.country,
|
|
125
|
-
discountCodes: discountCodes.length > 0 ? discountCodes : void 0
|
|
125
|
+
discountCodes: discountCodes.length > 0 ? discountCodes : void 0,
|
|
126
|
+
attributes: input.attributes
|
|
126
127
|
});
|
|
127
128
|
if (!cart?.checkoutUrl) {
|
|
128
129
|
throw new BuyNowCartCreationError({
|
package/cart/cart-actions.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export declare function createCartAction(options?: {
|
|
|
32
32
|
lines?: CartLinePayload[];
|
|
33
33
|
skipStoringCart?: boolean;
|
|
34
34
|
discountCodes?: string[];
|
|
35
|
+
attributes?: {
|
|
36
|
+
key: string;
|
|
37
|
+
value: string;
|
|
38
|
+
}[];
|
|
35
39
|
country?: StorefrontCountryCode;
|
|
36
40
|
}): Promise<Cart | null>;
|
|
37
41
|
/**
|
package/cart/cart-actions.js
CHANGED
|
@@ -65,6 +65,7 @@ async function createCartAction(options) {
|
|
|
65
65
|
lines,
|
|
66
66
|
skipStoringCart = false,
|
|
67
67
|
discountCodes,
|
|
68
|
+
attributes,
|
|
68
69
|
country
|
|
69
70
|
} = options ?? {};
|
|
70
71
|
const checkoutProvider = await getCheckoutProvider();
|
|
@@ -72,6 +73,7 @@ async function createCartAction(options) {
|
|
|
72
73
|
const cart = await cartGateway.createCart({
|
|
73
74
|
lines,
|
|
74
75
|
discountCodes,
|
|
76
|
+
attributes,
|
|
75
77
|
buyerIdentity: country ? { country } : void 0
|
|
76
78
|
});
|
|
77
79
|
if (cart && !skipStoringCart) {
|
package/cart/cart-provider.d.ts
CHANGED
|
@@ -66,6 +66,8 @@ export interface CartContextTypeInternal {
|
|
|
66
66
|
* For buy now functionality, use useBuyNow.
|
|
67
67
|
*/
|
|
68
68
|
export interface CartContextType {
|
|
69
|
+
/** Current cart ID for integrations that track checkout attribution. */
|
|
70
|
+
cartId: string | null;
|
|
69
71
|
/** Total number of items in cart */
|
|
70
72
|
itemsCount: number;
|
|
71
73
|
/** Whether the cart UI is open */
|
package/cart/cart-provider.js
CHANGED
|
@@ -11,6 +11,10 @@ export interface CartGateway {
|
|
|
11
11
|
createCart(options?: {
|
|
12
12
|
lines?: CartLinePayload[];
|
|
13
13
|
discountCodes?: string[];
|
|
14
|
+
attributes?: {
|
|
15
|
+
key: string;
|
|
16
|
+
value: string;
|
|
17
|
+
}[];
|
|
14
18
|
buyerIdentity?: CartBuyerIdentity;
|
|
15
19
|
}): Promise<Cart | null>;
|
|
16
20
|
addToCart(cartPayload: AddToCartPayload): Promise<Cart | null>;
|
|
@@ -11,6 +11,7 @@ class ResolverCartGateway {
|
|
|
11
11
|
async createCart({
|
|
12
12
|
lines,
|
|
13
13
|
discountCodes,
|
|
14
|
+
attributes,
|
|
14
15
|
buyerIdentity
|
|
15
16
|
} = {}) {
|
|
16
17
|
try {
|
|
@@ -26,6 +27,7 @@ class ResolverCartGateway {
|
|
|
26
27
|
sellingPlanId: line.sellingPlanId
|
|
27
28
|
})),
|
|
28
29
|
discountCodes,
|
|
30
|
+
attributes,
|
|
29
31
|
country: buyerIdentity?.country
|
|
30
32
|
});
|
|
31
33
|
} catch (error) {
|
|
@@ -81,5 +81,10 @@ export interface VariantBuyNowInfo {
|
|
|
81
81
|
export declare function useBuyNow(): {
|
|
82
82
|
buyNow: (variants: VariantBuyNowInfo[], options?: {
|
|
83
83
|
discountCodes?: string[];
|
|
84
|
+
/** Order-level Shopify cart attributes, including experiment attribution. */
|
|
85
|
+
attributes?: {
|
|
86
|
+
key: string;
|
|
87
|
+
value: string;
|
|
88
|
+
}[];
|
|
84
89
|
}) => Promise<BuyNowOutcome>;
|
|
85
90
|
};
|
|
@@ -35,6 +35,7 @@ function useBuyNow() {
|
|
|
35
35
|
properties: variant.properties ?? []
|
|
36
36
|
})),
|
|
37
37
|
discountCodes: options?.discountCodes ?? [],
|
|
38
|
+
attributes: options?.attributes ?? [],
|
|
38
39
|
pageUrl: window.location.href
|
|
39
40
|
};
|
|
40
41
|
const attemptStorageKey = `replo-checkout-attempt:${JSON.stringify(checkoutInput)}`;
|
package/gateways/canopy-api.d.ts
CHANGED
|
@@ -72,6 +72,10 @@ declare class CanopyApiGateway {
|
|
|
72
72
|
sellingPlanId?: string | null;
|
|
73
73
|
}[];
|
|
74
74
|
discountCodes?: string[];
|
|
75
|
+
attributes?: {
|
|
76
|
+
key: string;
|
|
77
|
+
value: string;
|
|
78
|
+
}[];
|
|
75
79
|
country?: StorefrontCountryCode;
|
|
76
80
|
}): Promise<Cart>;
|
|
77
81
|
cartAddLines({ cartId, lines, }: {
|
package/gateways/canopy-api.js
CHANGED
|
@@ -195,6 +195,7 @@ If you're running locally, make sure the canopy-api cloudflare worker is running
|
|
|
195
195
|
return this._cartPost("/create", {
|
|
196
196
|
lines: options?.lines,
|
|
197
197
|
discountCodes: options?.discountCodes,
|
|
198
|
+
attributes: options?.attributes,
|
|
198
199
|
country: options?.country
|
|
199
200
|
});
|
|
200
201
|
}
|
package/lib/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-10-
|
|
5
|
+
"commit": "a9c1282810e81faf573bd8fdb6a715918c68e247",
|
|
6
|
+
"builtAt": "2026-10-13T18:59:37.697Z"
|
|
7
7
|
};
|
package/loaders/loader-keys.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* `<integration>.<objectType>_<qualifier>`.
|
|
11
11
|
*/
|
|
12
12
|
export declare const DATA_LOADER_KEYS: {
|
|
13
|
+
readonly SHOPIFY_INTEGRATION_DETAILS: "shopify_storefront.integration_details";
|
|
13
14
|
readonly SHOPIFY_PRODUCT: "shopify_storefront.product";
|
|
14
15
|
readonly SHOPIFY_COLLECTION: "shopify_storefront.collection";
|
|
15
16
|
readonly SHOPIFY_COLLECTION_PRODUCTS: "shopify_storefront.collection_products";
|
package/loaders/loader-keys.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const DATA_LOADER_KEYS = {
|
|
2
|
+
SHOPIFY_INTEGRATION_DETAILS: "shopify_storefront.integration_details",
|
|
2
3
|
SHOPIFY_PRODUCT: "shopify_storefront.product",
|
|
3
4
|
SHOPIFY_COLLECTION: "shopify_storefront.collection",
|
|
4
5
|
SHOPIFY_COLLECTION_PRODUCTS: "shopify_storefront.collection_products",
|
|
@@ -1098,3 +1098,8 @@ export type ShopifyKachingBundlesLoaderOutput = z.infer<typeof shopifyKachingBun
|
|
|
1098
1098
|
export type StorefrontMetaobject = z.infer<typeof storefrontMetaobjectSchema>;
|
|
1099
1099
|
export type ShopifyMetaobjectLoaderOutput = z.infer<typeof shopifyMetaobjectLoaderOutputSchema>;
|
|
1100
1100
|
export type ShopifyMetaobjectsLoaderOutput = z.infer<typeof shopifyMetaobjectsLoaderOutputSchema>;
|
|
1101
|
+
export declare const shopifyIntegrationDetailsLoaderOutputSchema: z.ZodObject<{
|
|
1102
|
+
shopifyDomain: z.ZodString;
|
|
1103
|
+
storefrontAccessToken: z.ZodString;
|
|
1104
|
+
}, z.core.$strip>;
|
|
1105
|
+
export type ShopifyIntegrationDetails = z.infer<typeof shopifyIntegrationDetailsLoaderOutputSchema>;
|
|
@@ -362,6 +362,14 @@ const shopifyMetaobjectsLoaderOutputSchema = z.object({
|
|
|
362
362
|
const shopifyKachingBundlesLoaderOutputSchema = z.object({
|
|
363
363
|
bundles: z.record(z.string(), z.unknown()).nullable()
|
|
364
364
|
}).describe("ShopifyKachingBundles");
|
|
365
|
+
const shopifyIntegrationDetailsLoaderOutputSchema = z.object({
|
|
366
|
+
shopifyDomain: z.string().min(1).describe(
|
|
367
|
+
"The connected store's myshopify.com domain, without a protocol."
|
|
368
|
+
),
|
|
369
|
+
storefrontAccessToken: z.string().min(1).describe(
|
|
370
|
+
"Public Shopify Storefront API token intended for browser use. Never an Admin API or private Storefront token."
|
|
371
|
+
)
|
|
372
|
+
});
|
|
365
373
|
export {
|
|
366
374
|
contentfulAssetObjectSchema,
|
|
367
375
|
contentfulEntriesLoaderOutputSchema,
|
|
@@ -400,6 +408,7 @@ export {
|
|
|
400
408
|
sellingPlanOptionValueSchema,
|
|
401
409
|
sellingPlanPriceAdjustmentSchema,
|
|
402
410
|
sellingPlanSchema,
|
|
411
|
+
shopifyIntegrationDetailsLoaderOutputSchema,
|
|
403
412
|
shopifyKachingBundlesLoaderOutputSchema,
|
|
404
413
|
shopifyMetaobjectLoaderOutputSchema,
|
|
405
414
|
shopifyMetaobjectsLoaderOutputSchema,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { ShopifyIntegrationDetails } from "./loader-schemas";
|
|
3
|
+
type ShopifyIntegrationDetailsLoaderProps = {
|
|
4
|
+
loaderKey: string;
|
|
5
|
+
children: (data: ShopifyIntegrationDetails) => ReactNode;
|
|
6
|
+
fallback?: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export declare function ShopifyIntegrationDetailsLoader({ loaderKey, children, fallback, }: ShopifyIntegrationDetailsLoaderProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
5
|
+
import { invokeLoader } from "./invoke-loader";
|
|
6
|
+
import { LoaderErrorBoundary } from "./loader-error-boundary";
|
|
7
|
+
import { shopifyIntegrationDetailsLoaderOutputSchema } from "./loader-schemas";
|
|
8
|
+
function ShopifyIntegrationDetailsLoaderInner({
|
|
9
|
+
loaderKey,
|
|
10
|
+
children
|
|
11
|
+
}) {
|
|
12
|
+
const { data } = useSuspenseQuery({
|
|
13
|
+
queryKey: [loaderKey, {}],
|
|
14
|
+
queryFn: async () => {
|
|
15
|
+
const loadedData = await invokeLoader({
|
|
16
|
+
loaderKey,
|
|
17
|
+
args: {}
|
|
18
|
+
});
|
|
19
|
+
return shopifyIntegrationDetailsLoaderOutputSchema.parse(loadedData);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children(data) });
|
|
23
|
+
}
|
|
24
|
+
function ShopifyIntegrationDetailsLoader({
|
|
25
|
+
loaderKey,
|
|
26
|
+
children,
|
|
27
|
+
fallback
|
|
28
|
+
}) {
|
|
29
|
+
return /* @__PURE__ */ jsx(LoaderErrorBoundary, { fallback: fallback ?? null, resetKey: loaderKey, children: /* @__PURE__ */ jsx(Suspense, { fallback: fallback ?? null, children: /* @__PURE__ */ jsx(ShopifyIntegrationDetailsLoaderInner, { loaderKey, children }) }) });
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
ShopifyIntegrationDetailsLoader
|
|
33
|
+
};
|
package/next/open-next.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
defineCloudflareConfig,
|
|
3
|
+
getCloudflareContext
|
|
4
|
+
} from "@opennextjs/cloudflare";
|
|
2
5
|
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
|
|
3
6
|
import { withRegionalCache } from "@opennextjs/cloudflare/overrides/incremental-cache/regional-cache";
|
|
7
|
+
import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
|
|
8
|
+
import queueCache from "@opennextjs/cloudflare/overrides/queue/queue-cache";
|
|
4
9
|
import doShardedTagCache from "@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache";
|
|
10
|
+
const durableQueue = queueCache(doQueue);
|
|
11
|
+
const backgroundDurableQueue = {
|
|
12
|
+
name: "background-durable-queue",
|
|
13
|
+
send: async (message) => {
|
|
14
|
+
getCloudflareContext().ctx.waitUntil(durableQueue.send(message));
|
|
15
|
+
}
|
|
16
|
+
};
|
|
5
17
|
var open_next_default = defineCloudflareConfig({
|
|
6
18
|
incrementalCache: withRegionalCache(r2IncrementalCache, {
|
|
7
19
|
mode: "short-lived"
|
|
8
20
|
}),
|
|
9
21
|
enableCacheInterception: false,
|
|
22
|
+
queue: backgroundDurableQueue,
|
|
10
23
|
tagCache: doShardedTagCache({
|
|
11
24
|
baseShardSize: 12,
|
|
12
25
|
regionalCache: true,
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sdk",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.17.0",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-10-
|
|
8
|
+
"commit": "a9c1282810e81faf573bd8fdb6a715918c68e247",
|
|
9
|
+
"builtAt": "2026-10-13T18:59:37.697Z"
|
|
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",
|
|
@@ -85,6 +85,10 @@
|
|
|
85
85
|
"types": "./analytics/analytics-provider.d.ts",
|
|
86
86
|
"default": "./analytics/analytics-provider.js"
|
|
87
87
|
},
|
|
88
|
+
"./analytics/sinks/intelligems-sink": {
|
|
89
|
+
"types": "./analytics/sinks/intelligems-sink.d.ts",
|
|
90
|
+
"default": "./analytics/sinks/intelligems-sink.js"
|
|
91
|
+
},
|
|
88
92
|
"./analytics/hooks/use-product-viewed-analytics": {
|
|
89
93
|
"types": "./analytics/hooks/use-product-viewed-analytics.d.ts",
|
|
90
94
|
"default": "./analytics/hooks/use-product-viewed-analytics.js"
|
|
@@ -165,6 +169,10 @@
|
|
|
165
169
|
"types": "./loaders/reviews-io-reviews-loader.d.ts",
|
|
166
170
|
"default": "./loaders/reviews-io-reviews-loader.js"
|
|
167
171
|
},
|
|
172
|
+
"./loaders/shopify-integration-details-loader": {
|
|
173
|
+
"types": "./loaders/shopify-integration-details-loader.d.ts",
|
|
174
|
+
"default": "./loaders/shopify-integration-details-loader.js"
|
|
175
|
+
},
|
|
168
176
|
"./loaders/smile-earning-rules-loader": {
|
|
169
177
|
"types": "./loaders/smile-earning-rules-loader.d.ts",
|
|
170
178
|
"default": "./loaders/smile-earning-rules-loader.js"
|