@commercengine/js 0.3.4 → 0.3.5
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/package.json +3 -10
- package/dist/index.cjs +0 -532
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -456
- package/dist/index.d.cts.map +0 -1
package/package.json
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercengine/js",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Commerce Engine Checkout - Embeddable checkout SDK",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.cjs",
|
|
7
6
|
"module": "dist/index.mjs",
|
|
8
7
|
"types": "dist/index.d.mts",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
"default": "./dist/index.mjs"
|
|
14
|
-
},
|
|
15
|
-
"require": {
|
|
16
|
-
"types": "./dist/index.d.cts",
|
|
17
|
-
"default": "./dist/index.cjs"
|
|
18
|
-
}
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"default": "./dist/index.mjs"
|
|
19
12
|
},
|
|
20
13
|
"./cdn": "./dist/index.iife.js",
|
|
21
14
|
"./package.json": "./package.json"
|
package/dist/index.cjs
DELETED
|
@@ -1,532 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
-
|
|
3
|
-
//#region src/events.ts
|
|
4
|
-
var EventEmitter = class {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.listeners = /* @__PURE__ */ new Map();
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Subscribe to an event
|
|
10
|
-
*/
|
|
11
|
-
on(event, listener) {
|
|
12
|
-
if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
13
|
-
this.listeners.get(event)?.add(listener);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Unsubscribe from an event
|
|
17
|
-
*/
|
|
18
|
-
off(event, listener) {
|
|
19
|
-
const eventListeners = this.listeners.get(event);
|
|
20
|
-
if (eventListeners) eventListeners.delete(listener);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Subscribe to an event (once)
|
|
24
|
-
*/
|
|
25
|
-
once(event, listener) {
|
|
26
|
-
const onceListener = (data) => {
|
|
27
|
-
this.off(event, onceListener);
|
|
28
|
-
listener(data);
|
|
29
|
-
};
|
|
30
|
-
this.on(event, onceListener);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Emit an event to all subscribers
|
|
34
|
-
*/
|
|
35
|
-
emit(event, data) {
|
|
36
|
-
const eventListeners = this.listeners.get(event);
|
|
37
|
-
if (eventListeners) for (const listener of eventListeners) try {
|
|
38
|
-
listener(data);
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error(`[Commercengine] Error in ${event} listener:`, error);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Remove all listeners
|
|
45
|
-
*/
|
|
46
|
-
removeAllListeners() {
|
|
47
|
-
this.listeners.clear();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
//#endregion
|
|
52
|
-
//#region src/iframe-manager.ts
|
|
53
|
-
var IframeManager = class {
|
|
54
|
-
constructor() {
|
|
55
|
-
this.iframe = null;
|
|
56
|
-
this.container = null;
|
|
57
|
-
this.checkoutOrigin = null;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Create and mount the iframe (hidden initially)
|
|
61
|
-
*/
|
|
62
|
-
create(url, zIndex) {
|
|
63
|
-
if (this.container) {
|
|
64
|
-
console.warn("[Commercengine] Iframe already created");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
this.checkoutOrigin = new URL(url).origin;
|
|
68
|
-
this.container = document.createElement("div");
|
|
69
|
-
this.container.id = "commercengine-checkout";
|
|
70
|
-
this.container.style.cssText = `
|
|
71
|
-
position: fixed;
|
|
72
|
-
inset: 0;
|
|
73
|
-
z-index: ${zIndex};
|
|
74
|
-
pointer-events: none;
|
|
75
|
-
`;
|
|
76
|
-
this.iframe = document.createElement("iframe");
|
|
77
|
-
this.iframe.id = "commercengine-checkout-iframe";
|
|
78
|
-
this.iframe.title = "Shopping cart and checkout";
|
|
79
|
-
this.iframe.src = url;
|
|
80
|
-
this.iframe.allow = "payment";
|
|
81
|
-
this.iframe.style.cssText = `
|
|
82
|
-
width: 100%;
|
|
83
|
-
height: 100%;
|
|
84
|
-
border: none;
|
|
85
|
-
pointer-events: inherit;
|
|
86
|
-
background-color: transparent;
|
|
87
|
-
`;
|
|
88
|
-
this.container.appendChild(this.iframe);
|
|
89
|
-
document.body.appendChild(this.container);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Show the checkout overlay (enable pointer events + backdrop)
|
|
93
|
-
* Backdrop provides consistent dark overlay with blur, matching css-drawer's backdrop.
|
|
94
|
-
* This ensures the brand site is obscured even during payment gateway redirects.
|
|
95
|
-
*/
|
|
96
|
-
show() {
|
|
97
|
-
if (this.container) {
|
|
98
|
-
this.container.style.pointerEvents = "auto";
|
|
99
|
-
this.container.style.background = "hsl(0 0% 0% / 0.4)";
|
|
100
|
-
this.container.style.backdropFilter = "blur(4px)";
|
|
101
|
-
this.container.style.webkitBackdropFilter = "blur(4px)";
|
|
102
|
-
document.body.style.overflow = "hidden";
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Hide the checkout overlay (disable pointer events + remove backdrop)
|
|
107
|
-
*/
|
|
108
|
-
hide() {
|
|
109
|
-
if (this.container) {
|
|
110
|
-
this.container.style.pointerEvents = "none";
|
|
111
|
-
this.container.style.background = "";
|
|
112
|
-
this.container.style.backdropFilter = "";
|
|
113
|
-
this.container.style.webkitBackdropFilter = "";
|
|
114
|
-
document.body.style.overflow = "";
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Check if iframe is visible
|
|
119
|
-
*/
|
|
120
|
-
isVisible() {
|
|
121
|
-
return this.container?.style.pointerEvents === "auto";
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Send a message to the checkout iframe
|
|
125
|
-
*/
|
|
126
|
-
postMessage(type, data) {
|
|
127
|
-
if (!this.iframe?.contentWindow) {
|
|
128
|
-
console.warn("[Commercengine] Cannot send message - iframe not ready");
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (!this.checkoutOrigin) {
|
|
132
|
-
console.warn("[Commercengine] Cannot send message - checkout origin not established");
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
this.iframe.contentWindow.postMessage({
|
|
136
|
-
type,
|
|
137
|
-
data
|
|
138
|
-
}, this.checkoutOrigin);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Get the checkout origin for message validation
|
|
142
|
-
*/
|
|
143
|
-
getCheckoutOrigin() {
|
|
144
|
-
return this.checkoutOrigin;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Destroy the iframe and clean up
|
|
148
|
-
*/
|
|
149
|
-
destroy() {
|
|
150
|
-
if (this.container) {
|
|
151
|
-
this.container.remove();
|
|
152
|
-
this.container = null;
|
|
153
|
-
}
|
|
154
|
-
this.iframe = null;
|
|
155
|
-
this.checkoutOrigin = null;
|
|
156
|
-
document.body.style.overflow = "";
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
//#endregion
|
|
161
|
-
//#region src/checkout.ts
|
|
162
|
-
/**
|
|
163
|
-
* Checkout Class
|
|
164
|
-
*
|
|
165
|
-
* Main entry point for Commerce Engine Checkout integration.
|
|
166
|
-
* Manages iframe lifecycle, event handling, and provides public API.
|
|
167
|
-
*/
|
|
168
|
-
/** Checkout URLs by environment */
|
|
169
|
-
const CHECKOUT_URLS = {
|
|
170
|
-
production: "https://checkout.commercengine.com",
|
|
171
|
-
staging: "https://staging.checkout.commercengine.com"
|
|
172
|
-
};
|
|
173
|
-
/**
|
|
174
|
-
* Build checkout iframe URL
|
|
175
|
-
*/
|
|
176
|
-
function buildCheckoutUrl(storeId, apiKey, environment) {
|
|
177
|
-
return `${CHECKOUT_URLS[environment]}?store_id=${storeId}&api_key=${apiKey}&environment=${environment}&mode=iframe`;
|
|
178
|
-
}
|
|
179
|
-
var Checkout = class extends EventEmitter {
|
|
180
|
-
constructor(config) {
|
|
181
|
-
super();
|
|
182
|
-
this.isReady = false;
|
|
183
|
-
this.isOpen = false;
|
|
184
|
-
this.cartState = {
|
|
185
|
-
count: 0,
|
|
186
|
-
total: 0,
|
|
187
|
-
currency: "INR"
|
|
188
|
-
};
|
|
189
|
-
this.hasQuickBuyParams = false;
|
|
190
|
-
this.config = config;
|
|
191
|
-
this.iframe = new IframeManager();
|
|
192
|
-
this.boundMessageHandler = this.handleMessage.bind(this);
|
|
193
|
-
this.initialize();
|
|
194
|
-
}
|
|
195
|
-
initialize() {
|
|
196
|
-
let baseUrl;
|
|
197
|
-
if (this.config.url) baseUrl = this.config.url;
|
|
198
|
-
else if (this.config.storeId && this.config.apiKey) {
|
|
199
|
-
const env = this.config.environment || "production";
|
|
200
|
-
baseUrl = buildCheckoutUrl(this.config.storeId, this.config.apiKey, env);
|
|
201
|
-
} else throw new Error("[Commercengine] Either 'url' or both 'storeId' and 'apiKey' must be provided.");
|
|
202
|
-
const url = new URL(baseUrl);
|
|
203
|
-
url.searchParams.set("mode", "iframe");
|
|
204
|
-
if (this.config.storeId && !url.searchParams.has("store_id")) url.searchParams.set("store_id", this.config.storeId);
|
|
205
|
-
if (this.config.apiKey && !url.searchParams.has("api_key")) url.searchParams.set("api_key", this.config.apiKey);
|
|
206
|
-
if (this.config.environment && !url.searchParams.has("environment")) url.searchParams.set("environment", this.config.environment);
|
|
207
|
-
if (this.config.theme) url.searchParams.set("theme", this.config.theme);
|
|
208
|
-
if (this.config.authMode) url.searchParams.set("auth_mode", this.config.authMode);
|
|
209
|
-
if (this.config.accessToken) url.searchParams.set("token", this.config.accessToken);
|
|
210
|
-
if (this.config.refreshToken) url.searchParams.set("refresh_token", this.config.refreshToken);
|
|
211
|
-
let quickBuy = this.config.quickBuy;
|
|
212
|
-
let sessionMode = this.config.sessionMode;
|
|
213
|
-
if (this.config.autoDetectQuickBuy && !quickBuy) {
|
|
214
|
-
const parentParams = new URLSearchParams(window.location.search);
|
|
215
|
-
const productId = parentParams.get("product_id");
|
|
216
|
-
const variantId = parentParams.get("variant_id");
|
|
217
|
-
if (productId) {
|
|
218
|
-
quickBuy = {
|
|
219
|
-
productId,
|
|
220
|
-
variantId: variantId ?? null,
|
|
221
|
-
quantity: parseInt(parentParams.get("qty") || parentParams.get("quantity") || "1", 10)
|
|
222
|
-
};
|
|
223
|
-
const parentSessionMode = parentParams.get("session_mode");
|
|
224
|
-
if (parentSessionMode === "force-new" || parentSessionMode === "continue-existing") sessionMode = parentSessionMode;
|
|
225
|
-
setTimeout(() => this.cleanQuickBuyParamsFromUrl(), 0);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (quickBuy) {
|
|
229
|
-
this.hasQuickBuyParams = true;
|
|
230
|
-
url.searchParams.set("product_id", quickBuy.productId);
|
|
231
|
-
if (quickBuy.variantId) url.searchParams.set("variant_id", quickBuy.variantId);
|
|
232
|
-
if (quickBuy.quantity && quickBuy.quantity !== 1) url.searchParams.set("qty", String(quickBuy.quantity));
|
|
233
|
-
}
|
|
234
|
-
if (sessionMode) url.searchParams.set("session_mode", sessionMode);
|
|
235
|
-
if (this.config.features?.loyalty === false) url.searchParams.set("loyalty", "false");
|
|
236
|
-
if (this.config.features?.coupons === false) url.searchParams.set("coupons", "false");
|
|
237
|
-
if (this.config.features?.freeShippingProgress === false) url.searchParams.set("free_shipping_progress", "false");
|
|
238
|
-
if (this.config.features?.productRecommendations === false) url.searchParams.set("product_recommendations", "false");
|
|
239
|
-
if (this.config.features?.collectInStore === true) url.searchParams.set("collect_in_store", "true");
|
|
240
|
-
if (typeof window !== "undefined") url.searchParams.set("parent_origin", window.location.origin);
|
|
241
|
-
const zIndex = this.config.appearance?.zIndex ?? 99999;
|
|
242
|
-
this.iframe.create(url.toString(), zIndex);
|
|
243
|
-
window.addEventListener("message", this.boundMessageHandler);
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Remove quick buy params from the parent URL to prevent duplicate adds on refresh
|
|
247
|
-
* Uses replaceState to avoid adding to browser history
|
|
248
|
-
*/
|
|
249
|
-
cleanQuickBuyParamsFromUrl() {
|
|
250
|
-
if (typeof window === "undefined") return;
|
|
251
|
-
const url = new URL(window.location.href);
|
|
252
|
-
const paramsToRemove = [
|
|
253
|
-
"product_id",
|
|
254
|
-
"variant_id",
|
|
255
|
-
"qty",
|
|
256
|
-
"quantity",
|
|
257
|
-
"session_mode"
|
|
258
|
-
];
|
|
259
|
-
let hasChanges = false;
|
|
260
|
-
for (const param of paramsToRemove) if (url.searchParams.has(param)) {
|
|
261
|
-
url.searchParams.delete(param);
|
|
262
|
-
hasChanges = true;
|
|
263
|
-
}
|
|
264
|
-
if (hasChanges) window.history.replaceState({}, "", url.toString());
|
|
265
|
-
}
|
|
266
|
-
handleMessage(event) {
|
|
267
|
-
const expectedOrigin = this.iframe.getCheckoutOrigin();
|
|
268
|
-
if (!expectedOrigin || event.origin !== expectedOrigin) return;
|
|
269
|
-
const { type, data } = event.data || {};
|
|
270
|
-
if (!type) return;
|
|
271
|
-
switch (type) {
|
|
272
|
-
case "checkout:ready":
|
|
273
|
-
this.handleReady();
|
|
274
|
-
break;
|
|
275
|
-
case "checkout:open":
|
|
276
|
-
this.handleOpen();
|
|
277
|
-
break;
|
|
278
|
-
case "checkout:close":
|
|
279
|
-
this.handleClose();
|
|
280
|
-
break;
|
|
281
|
-
case "checkout:complete":
|
|
282
|
-
this.handleComplete(data);
|
|
283
|
-
break;
|
|
284
|
-
case "checkout:error":
|
|
285
|
-
this.handleError(data);
|
|
286
|
-
break;
|
|
287
|
-
case "cart:updated":
|
|
288
|
-
this.handleCartUpdate(data);
|
|
289
|
-
break;
|
|
290
|
-
case "auth:login":
|
|
291
|
-
this.handleLogin(data);
|
|
292
|
-
break;
|
|
293
|
-
case "auth:logout":
|
|
294
|
-
this.handleLogout(data);
|
|
295
|
-
break;
|
|
296
|
-
case "auth:refresh":
|
|
297
|
-
this.handleTokenRefresh(data);
|
|
298
|
-
break;
|
|
299
|
-
case "auth:session-error":
|
|
300
|
-
this.handleSessionError();
|
|
301
|
-
break;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
handleReady() {
|
|
305
|
-
this.isReady = true;
|
|
306
|
-
this.config.onReady?.();
|
|
307
|
-
this.emit("ready");
|
|
308
|
-
if (this.hasQuickBuyParams) this.openCart();
|
|
309
|
-
}
|
|
310
|
-
handleError(data) {
|
|
311
|
-
this.isReady = true;
|
|
312
|
-
this.config.onError?.(data);
|
|
313
|
-
this.emit("error", data);
|
|
314
|
-
}
|
|
315
|
-
handleOpen() {
|
|
316
|
-
this.iframe.show();
|
|
317
|
-
this.isOpen = true;
|
|
318
|
-
this.config.onOpen?.();
|
|
319
|
-
this.emit("open");
|
|
320
|
-
}
|
|
321
|
-
handleClose() {
|
|
322
|
-
this.iframe.hide();
|
|
323
|
-
this.isOpen = false;
|
|
324
|
-
this.config.onClose?.();
|
|
325
|
-
this.emit("close");
|
|
326
|
-
}
|
|
327
|
-
handleComplete(data) {
|
|
328
|
-
this.config.onComplete?.(data);
|
|
329
|
-
this.emit("complete", data);
|
|
330
|
-
}
|
|
331
|
-
handleCartUpdate(data) {
|
|
332
|
-
this.cartState = data;
|
|
333
|
-
this.config.onCartUpdate?.(data);
|
|
334
|
-
this.emit("cart:updated", data);
|
|
335
|
-
}
|
|
336
|
-
handleLogin(data) {
|
|
337
|
-
this.config.onLogin?.(data);
|
|
338
|
-
this.emit("auth:login", data);
|
|
339
|
-
}
|
|
340
|
-
handleLogout(data) {
|
|
341
|
-
this.config.onLogout?.(data);
|
|
342
|
-
this.emit("auth:logout", data);
|
|
343
|
-
}
|
|
344
|
-
handleTokenRefresh(data) {
|
|
345
|
-
this.config.onTokenRefresh?.(data);
|
|
346
|
-
this.emit("auth:refresh", data);
|
|
347
|
-
}
|
|
348
|
-
handleSessionError() {
|
|
349
|
-
this.config.onSessionError?.();
|
|
350
|
-
this.emit("auth:session-error");
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Open the cart drawer
|
|
354
|
-
*/
|
|
355
|
-
openCart() {
|
|
356
|
-
if (!this.isReady) {
|
|
357
|
-
console.warn("[Commercengine] Not ready. Wait for onReady callback or 'ready' event.");
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
this.iframe.show();
|
|
361
|
-
this.isOpen = true;
|
|
362
|
-
this.iframe.postMessage("checkout:open-cart");
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Open the checkout drawer directly (e.g., for Buy Now flow)
|
|
366
|
-
*/
|
|
367
|
-
openCheckout() {
|
|
368
|
-
if (!this.isReady) {
|
|
369
|
-
console.warn("[Commercengine] Not ready. Wait for onReady callback or 'ready' event.");
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
this.iframe.show();
|
|
373
|
-
this.isOpen = true;
|
|
374
|
-
this.iframe.postMessage("checkout:open-checkout");
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Close the checkout overlay
|
|
378
|
-
*/
|
|
379
|
-
close() {
|
|
380
|
-
this.iframe.hide();
|
|
381
|
-
this.isOpen = false;
|
|
382
|
-
this.iframe.postMessage("checkout:close");
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Update authentication tokens
|
|
386
|
-
* Use this when user logs in/out on the parent site
|
|
387
|
-
*/
|
|
388
|
-
updateTokens(accessToken, refreshToken) {
|
|
389
|
-
if (!this.isReady) {
|
|
390
|
-
this.config.accessToken = accessToken;
|
|
391
|
-
this.config.refreshToken = refreshToken;
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
this.iframe.postMessage("checkout:update-tokens", {
|
|
395
|
-
accessToken,
|
|
396
|
-
refreshToken
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Add an item to cart and open the cart drawer
|
|
401
|
-
*
|
|
402
|
-
* @param productId - Product ID (required)
|
|
403
|
-
* @param variantId - Variant ID (required, null for non-variant products)
|
|
404
|
-
* @param quantity - Quantity to add (default: 1)
|
|
405
|
-
*/
|
|
406
|
-
addToCart(productId, variantId, quantity = 1) {
|
|
407
|
-
if (!this.isReady) {
|
|
408
|
-
console.warn("[Commercengine] Not ready. Wait for onReady callback or 'ready' event.");
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
this.iframe.postMessage("checkout:add-item", {
|
|
412
|
-
productId,
|
|
413
|
-
variantId,
|
|
414
|
-
quantity
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Get current cart state
|
|
419
|
-
*/
|
|
420
|
-
getCart() {
|
|
421
|
-
return { ...this.cartState };
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Check if checkout is ready
|
|
425
|
-
*/
|
|
426
|
-
get ready() {
|
|
427
|
-
return this.isReady;
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Check if checkout overlay is currently open
|
|
431
|
-
*/
|
|
432
|
-
get open() {
|
|
433
|
-
return this.isOpen;
|
|
434
|
-
}
|
|
435
|
-
on(event, listener) {
|
|
436
|
-
super.on(event, listener);
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Destroy the checkout instance
|
|
440
|
-
* Removes iframe and cleans up event listeners
|
|
441
|
-
*/
|
|
442
|
-
destroy() {
|
|
443
|
-
window.removeEventListener("message", this.boundMessageHandler);
|
|
444
|
-
this.iframe.destroy();
|
|
445
|
-
this.removeAllListeners();
|
|
446
|
-
this.isReady = false;
|
|
447
|
-
this.isOpen = false;
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
//#endregion
|
|
452
|
-
//#region src/index.ts
|
|
453
|
-
/**
|
|
454
|
-
* Commerce Engine Checkout
|
|
455
|
-
*
|
|
456
|
-
* @commercengine/js - Embeddable checkout SDK
|
|
457
|
-
*
|
|
458
|
-
* @example CDN Usage (Vanilla JS):
|
|
459
|
-
* ```html
|
|
460
|
-
* <script src="https://cdn.commercengine.com/v1.js" async><\/script>
|
|
461
|
-
* <script>
|
|
462
|
-
* window.Commercengine.onLoad = async () => {
|
|
463
|
-
* const checkout = await Commercengine.init({
|
|
464
|
-
* storeId: "store_xxx",
|
|
465
|
-
* apiKey: "ak_xxx",
|
|
466
|
-
* theme: "dark",
|
|
467
|
-
* onComplete: (order) => console.log("Order:", order.orderNumber),
|
|
468
|
-
* });
|
|
469
|
-
*
|
|
470
|
-
* document.getElementById("cart-btn").onclick = () => checkout.openCart();
|
|
471
|
-
* };
|
|
472
|
-
* <\/script>
|
|
473
|
-
* ```
|
|
474
|
-
*
|
|
475
|
-
* @example ESM Import:
|
|
476
|
-
* ```typescript
|
|
477
|
-
* import { Commercengine } from "@commercengine/js";
|
|
478
|
-
*
|
|
479
|
-
* const checkout = await Commercengine.init({
|
|
480
|
-
* storeId: "store_xxx",
|
|
481
|
-
* apiKey: "ak_xxx",
|
|
482
|
-
* });
|
|
483
|
-
*
|
|
484
|
-
* checkout.on("cart:updated", (cart) => updateBadge(cart.count));
|
|
485
|
-
* checkout.openCart();
|
|
486
|
-
* ```
|
|
487
|
-
*/
|
|
488
|
-
/**
|
|
489
|
-
* Global Commercengine namespace
|
|
490
|
-
*/
|
|
491
|
-
const Commercengine = { init: async (config) => {
|
|
492
|
-
if (!config.url && (!config.storeId || !config.apiKey)) throw new Error("[Commercengine] Either 'url' or both 'storeId' and 'apiKey' must be provided");
|
|
493
|
-
if (Commercengine.instance) Commercengine.instance.destroy();
|
|
494
|
-
const checkout = new Checkout(config);
|
|
495
|
-
Commercengine.instance = checkout;
|
|
496
|
-
return new Promise((resolve, reject) => {
|
|
497
|
-
if (checkout.ready) {
|
|
498
|
-
resolve(checkout);
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
const timeout = setTimeout(() => {
|
|
502
|
-
reject(/* @__PURE__ */ new Error("Checkout initialization timed out"));
|
|
503
|
-
}, 3e4);
|
|
504
|
-
checkout.once("ready", () => {
|
|
505
|
-
clearTimeout(timeout);
|
|
506
|
-
resolve(checkout);
|
|
507
|
-
});
|
|
508
|
-
checkout.once("error", () => {
|
|
509
|
-
clearTimeout(timeout);
|
|
510
|
-
resolve(checkout);
|
|
511
|
-
});
|
|
512
|
-
});
|
|
513
|
-
} };
|
|
514
|
-
if (typeof window !== "undefined") {
|
|
515
|
-
const existingOnLoad = window.Commercengine?.onLoad;
|
|
516
|
-
window.Commercengine = Commercengine;
|
|
517
|
-
if (existingOnLoad) {
|
|
518
|
-
Commercengine.onLoad = existingOnLoad;
|
|
519
|
-
try {
|
|
520
|
-
existingOnLoad();
|
|
521
|
-
} catch (error) {
|
|
522
|
-
console.error("[Commercengine] Error in onLoad callback:", error);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
var src_default = Commercengine;
|
|
527
|
-
|
|
528
|
-
//#endregion
|
|
529
|
-
exports.Checkout = Checkout;
|
|
530
|
-
exports.Commercengine = Commercengine;
|
|
531
|
-
exports.default = src_default;
|
|
532
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/events.ts","../src/iframe-manager.ts","../src/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple Event Emitter\n *\n * Provides pub/sub functionality for checkout events.\n */\n\nimport type { CheckoutEventType, EventListener } from \"./types\";\n\nexport class EventEmitter {\n private listeners: Map<CheckoutEventType, Set<EventListener>> = new Map();\n\n /**\n * Subscribe to an event\n */\n on<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)?.add(listener as EventListener);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Subscribe to an event (once)\n */\n once<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void {\n const onceListener: EventListener<T> = (data) => {\n this.off(event, onceListener);\n listener(data);\n };\n this.on(event, onceListener);\n }\n\n /**\n * Emit an event to all subscribers\n */\n protected emit<T = unknown>(event: CheckoutEventType, data?: T): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n for (const listener of eventListeners) {\n try {\n listener(data);\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: Intentional error logging\n console.error(`[Commercengine] Error in ${event} listener:`, error);\n }\n }\n }\n }\n\n /**\n * Remove all listeners\n */\n protected removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","/**\n * Iframe Manager\n *\n * Handles iframe creation, lifecycle, and visibility management.\n * The iframe is pre-mounted (hidden) on init and shown on demand.\n */\n\nimport type { OutgoingEventType } from \"./types\";\n\nexport class IframeManager {\n private iframe: HTMLIFrameElement | null = null;\n private container: HTMLDivElement | null = null;\n private checkoutOrigin: string | null = null;\n\n /**\n * Create and mount the iframe (hidden initially)\n */\n create(url: string, zIndex: number): void {\n if (this.container) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning\n console.warn(\"[Commercengine] Iframe already created\");\n return;\n }\n\n // Store origin for postMessage security\n this.checkoutOrigin = new URL(url).origin;\n\n // Create container (covers viewport, initially non-interactive)\n this.container = document.createElement(\"div\");\n this.container.id = \"commercengine-checkout\";\n this.container.style.cssText = `\n position: fixed;\n inset: 0;\n z-index: ${zIndex};\n pointer-events: none;\n `;\n\n // Create iframe\n this.iframe = document.createElement(\"iframe\");\n this.iframe.id = \"commercengine-checkout-iframe\";\n this.iframe.title = \"Shopping cart and checkout\";\n this.iframe.src = url;\n this.iframe.allow = \"payment\";\n this.iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n pointer-events: inherit;\n background-color: transparent;\n `;\n\n this.container.appendChild(this.iframe);\n document.body.appendChild(this.container);\n }\n\n /**\n * Show the checkout overlay (enable pointer events + backdrop)\n * Backdrop provides consistent dark overlay with blur, matching css-drawer's backdrop.\n * This ensures the brand site is obscured even during payment gateway redirects.\n */\n show(): void {\n if (this.container) {\n this.container.style.pointerEvents = \"auto\";\n this.container.style.background = \"hsl(0 0% 0% / 0.4)\";\n this.container.style.backdropFilter = \"blur(4px)\";\n // @ts-expect-error - webkitBackdropFilter for Safari support\n this.container.style.webkitBackdropFilter = \"blur(4px)\";\n document.body.style.overflow = \"hidden\";\n }\n }\n\n /**\n * Hide the checkout overlay (disable pointer events + remove backdrop)\n */\n hide(): void {\n if (this.container) {\n this.container.style.pointerEvents = \"none\";\n this.container.style.background = \"\";\n this.container.style.backdropFilter = \"\";\n // @ts-expect-error - webkitBackdropFilter for Safari support\n this.container.style.webkitBackdropFilter = \"\";\n document.body.style.overflow = \"\";\n }\n }\n\n /**\n * Check if iframe is visible\n */\n isVisible(): boolean {\n return this.container?.style.pointerEvents === \"auto\";\n }\n\n /**\n * Send a message to the checkout iframe\n */\n postMessage(type: OutgoingEventType, data?: unknown): void {\n if (!this.iframe?.contentWindow) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning\n console.warn(\"[Commercengine] Cannot send message - iframe not ready\");\n return;\n }\n\n // Use specific origin for security - never use \"*\"\n if (!this.checkoutOrigin) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning for security\n console.warn(\"[Commercengine] Cannot send message - checkout origin not established\");\n return;\n }\n this.iframe.contentWindow.postMessage({ type, data }, this.checkoutOrigin);\n }\n\n /**\n * Get the checkout origin for message validation\n */\n getCheckoutOrigin(): string | null {\n return this.checkoutOrigin;\n }\n\n /**\n * Destroy the iframe and clean up\n */\n destroy(): void {\n if (this.container) {\n this.container.remove();\n this.container = null;\n }\n this.iframe = null;\n this.checkoutOrigin = null;\n\n // Restore body scroll\n document.body.style.overflow = \"\";\n }\n}\n","/**\n * Checkout Class\n *\n * Main entry point for Commerce Engine Checkout integration.\n * Manages iframe lifecycle, event handling, and provides public API.\n */\n\nimport { EventEmitter } from \"./events\";\nimport { IframeManager } from \"./iframe-manager\";\nimport type {\n AuthLoginData,\n AuthLogoutData,\n AuthRefreshData,\n CartData,\n CheckoutConfig,\n CheckoutEventType,\n Environment,\n EventListener,\n IncomingEventType,\n OrderData,\n} from \"./types\";\n\n// =============================================================================\n// URL RESOLUTION\n// =============================================================================\n\n/** Checkout URLs by environment */\nconst CHECKOUT_URLS: Record<Environment, string> = {\n production: \"https://checkout.commercengine.com\",\n staging: \"https://staging.checkout.commercengine.com\",\n};\n\n/**\n * Build checkout iframe URL\n */\nfunction buildCheckoutUrl(storeId: string, apiKey: string, environment: Environment): string {\n const baseUrl = CHECKOUT_URLS[environment];\n return `${baseUrl}?store_id=${storeId}&api_key=${apiKey}&environment=${environment}&mode=iframe`;\n}\n\n// =============================================================================\n// CHECKOUT CLASS\n// =============================================================================\n\nexport class Checkout extends EventEmitter {\n private config: CheckoutConfig;\n private iframe: IframeManager;\n private isReady = false;\n private isOpen = false;\n private cartState: CartData = { count: 0, total: 0, currency: \"INR\" };\n private boundMessageHandler: (event: MessageEvent) => void;\n private hasQuickBuyParams = false; // Track if we detected quick buy params\n\n constructor(config: CheckoutConfig) {\n super();\n this.config = config;\n this.iframe = new IframeManager();\n this.boundMessageHandler = this.handleMessage.bind(this);\n this.initialize();\n }\n\n // ===========================================================================\n // INITIALIZATION\n // ===========================================================================\n\n private initialize(): void {\n // Build checkout URL - use direct URL if provided, otherwise resolve from credentials\n let baseUrl: string;\n if (this.config.url) {\n // Direct URL provided (local development)\n baseUrl = this.config.url;\n } else if (this.config.storeId && this.config.apiKey) {\n // Build URL from credentials + environment\n const env = this.config.environment || \"production\";\n baseUrl = buildCheckoutUrl(this.config.storeId, this.config.apiKey, env);\n } else {\n throw new Error(\n \"[Commercengine] Either 'url' or both 'storeId' and 'apiKey' must be provided.\"\n );\n }\n\n const url = new URL(baseUrl);\n\n // Always set iframe mode\n url.searchParams.set(\"mode\", \"iframe\");\n\n // Add store credentials if provided and not already in URL\n if (this.config.storeId && !url.searchParams.has(\"store_id\")) {\n url.searchParams.set(\"store_id\", this.config.storeId);\n }\n if (this.config.apiKey && !url.searchParams.has(\"api_key\")) {\n url.searchParams.set(\"api_key\", this.config.apiKey);\n }\n if (this.config.environment && !url.searchParams.has(\"environment\")) {\n url.searchParams.set(\"environment\", this.config.environment);\n }\n\n // Add theme preference\n if (this.config.theme) {\n url.searchParams.set(\"theme\", this.config.theme);\n }\n\n // Add auth config\n if (this.config.authMode) {\n url.searchParams.set(\"auth_mode\", this.config.authMode);\n }\n if (this.config.accessToken) {\n url.searchParams.set(\"token\", this.config.accessToken);\n }\n if (this.config.refreshToken) {\n url.searchParams.set(\"refresh_token\", this.config.refreshToken);\n }\n\n // Auto-detect quick buy params from parent URL (if enabled and no explicit quickBuy)\n let quickBuy = this.config.quickBuy;\n let sessionMode = this.config.sessionMode;\n\n if (this.config.autoDetectQuickBuy && !quickBuy) {\n const parentParams = new URLSearchParams(window.location.search);\n const productId = parentParams.get(\"product_id\");\n const variantId = parentParams.get(\"variant_id\");\n\n if (productId) {\n quickBuy = {\n productId,\n variantId: variantId ?? null,\n quantity: parseInt(parentParams.get(\"qty\") || parentParams.get(\"quantity\") || \"1\", 10),\n };\n\n // Also check for session_mode in parent URL\n const parentSessionMode = parentParams.get(\"session_mode\");\n if (parentSessionMode === \"force-new\" || parentSessionMode === \"continue-existing\") {\n sessionMode = parentSessionMode;\n }\n\n // Clean quick buy params from URL to prevent duplicate adds on refresh\n // Deferred to next tick to handle React StrictMode double-mounting\n setTimeout(() => this.cleanQuickBuyParamsFromUrl(), 0);\n }\n }\n\n // Add quick buy params\n if (quickBuy) {\n this.hasQuickBuyParams = true;\n url.searchParams.set(\"product_id\", quickBuy.productId);\n if (quickBuy.variantId) {\n url.searchParams.set(\"variant_id\", quickBuy.variantId);\n }\n if (quickBuy.quantity && quickBuy.quantity !== 1) {\n url.searchParams.set(\"qty\", String(quickBuy.quantity));\n }\n }\n\n // Add session mode\n if (sessionMode) {\n url.searchParams.set(\"session_mode\", sessionMode);\n }\n\n // Add feature flags (only pass when overriding defaults)\n // Features default to true: pass when explicitly false\n if (this.config.features?.loyalty === false) {\n url.searchParams.set(\"loyalty\", \"false\");\n }\n if (this.config.features?.coupons === false) {\n url.searchParams.set(\"coupons\", \"false\");\n }\n if (this.config.features?.freeShippingProgress === false) {\n url.searchParams.set(\"free_shipping_progress\", \"false\");\n }\n if (this.config.features?.productRecommendations === false) {\n url.searchParams.set(\"product_recommendations\", \"false\");\n }\n // Features default to false: pass when explicitly true\n if (this.config.features?.collectInStore === true) {\n url.searchParams.set(\"collect_in_store\", \"true\");\n }\n\n // Pass parent origin for postMessage security\n // This allows the iframe to validate incoming messages and send responses to the correct origin\n if (typeof window !== \"undefined\") {\n url.searchParams.set(\"parent_origin\", window.location.origin);\n }\n\n // Create iframe (hidden initially, will show when ready + opened)\n const zIndex = this.config.appearance?.zIndex ?? 99999;\n this.iframe.create(url.toString(), zIndex);\n\n // Listen for messages from checkout iframe\n window.addEventListener(\"message\", this.boundMessageHandler);\n }\n\n // ===========================================================================\n // URL CLEANUP\n // ===========================================================================\n\n /**\n * Remove quick buy params from the parent URL to prevent duplicate adds on refresh\n * Uses replaceState to avoid adding to browser history\n */\n private cleanQuickBuyParamsFromUrl(): void {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n const paramsToRemove = [\"product_id\", \"variant_id\", \"qty\", \"quantity\", \"session_mode\"];\n\n let hasChanges = false;\n for (const param of paramsToRemove) {\n if (url.searchParams.has(param)) {\n url.searchParams.delete(param);\n hasChanges = true;\n }\n }\n\n if (hasChanges) {\n window.history.replaceState({}, \"\", url.toString());\n }\n }\n\n // ===========================================================================\n // MESSAGE HANDLING\n // ===========================================================================\n\n private handleMessage(event: MessageEvent): void {\n // Validate origin for security - reject if no expected origin or mismatch\n const expectedOrigin = this.iframe.getCheckoutOrigin();\n if (!expectedOrigin || event.origin !== expectedOrigin) {\n return;\n }\n\n const { type, data } = event.data || {};\n if (!type) return;\n\n switch (type as IncomingEventType) {\n case \"checkout:ready\":\n this.handleReady();\n break;\n\n case \"checkout:open\":\n this.handleOpen();\n break;\n\n case \"checkout:close\":\n this.handleClose();\n break;\n\n case \"checkout:complete\":\n this.handleComplete(data as OrderData);\n break;\n\n case \"checkout:error\":\n this.handleError(data as { message: string });\n break;\n\n case \"cart:updated\":\n this.handleCartUpdate(data as CartData);\n break;\n\n case \"auth:login\":\n this.handleLogin(data as AuthLoginData);\n break;\n\n case \"auth:logout\":\n this.handleLogout(data as AuthLogoutData);\n break;\n\n case \"auth:refresh\":\n this.handleTokenRefresh(data as AuthRefreshData);\n break;\n\n case \"auth:session-error\":\n this.handleSessionError();\n break;\n }\n }\n\n private handleReady(): void {\n this.isReady = true;\n this.config.onReady?.();\n this.emit(\"ready\");\n\n // Auto-open cart if we have quick buy params (from config or auto-detected URL)\n if (this.hasQuickBuyParams) {\n this.openCart();\n }\n }\n\n private handleError(data: { message: string }): void {\n // Set ready so user can still interact (they'll see the error drawer)\n this.isReady = true;\n this.config.onError?.(data);\n this.emit(\"error\", data);\n }\n\n private handleOpen(): void {\n this.iframe.show();\n this.isOpen = true;\n this.config.onOpen?.();\n this.emit(\"open\");\n }\n\n private handleClose(): void {\n this.iframe.hide();\n this.isOpen = false;\n this.config.onClose?.();\n this.emit(\"close\");\n }\n\n private handleComplete(data: OrderData): void {\n this.config.onComplete?.(data);\n this.emit(\"complete\", data);\n }\n\n private handleCartUpdate(data: CartData): void {\n this.cartState = data;\n this.config.onCartUpdate?.(data);\n this.emit(\"cart:updated\", data);\n }\n\n private handleLogin(data: AuthLoginData): void {\n this.config.onLogin?.(data);\n this.emit(\"auth:login\", data);\n }\n\n private handleLogout(data: AuthLogoutData): void {\n this.config.onLogout?.(data);\n this.emit(\"auth:logout\", data);\n }\n\n private handleTokenRefresh(data: AuthRefreshData): void {\n this.config.onTokenRefresh?.(data);\n this.emit(\"auth:refresh\", data);\n }\n\n private handleSessionError(): void {\n this.config.onSessionError?.();\n this.emit(\"auth:session-error\");\n }\n\n // ===========================================================================\n // PUBLIC API\n // ===========================================================================\n\n /**\n * Open the cart drawer\n */\n openCart(): void {\n if (!this.isReady) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning\n console.warn(\"[Commercengine] Not ready. Wait for onReady callback or 'ready' event.\");\n return;\n }\n\n this.iframe.show();\n this.isOpen = true;\n this.iframe.postMessage(\"checkout:open-cart\");\n }\n\n /**\n * Open the checkout drawer directly (e.g., for Buy Now flow)\n */\n openCheckout(): void {\n if (!this.isReady) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning\n console.warn(\"[Commercengine] Not ready. Wait for onReady callback or 'ready' event.\");\n return;\n }\n\n this.iframe.show();\n this.isOpen = true;\n this.iframe.postMessage(\"checkout:open-checkout\");\n }\n\n /**\n * Close the checkout overlay\n */\n close(): void {\n this.iframe.hide();\n this.isOpen = false;\n this.iframe.postMessage(\"checkout:close\");\n }\n\n /**\n * Update authentication tokens\n * Use this when user logs in/out on the parent site\n */\n updateTokens(accessToken: string, refreshToken?: string): void {\n if (!this.isReady) {\n // Store for when ready\n this.config.accessToken = accessToken;\n this.config.refreshToken = refreshToken;\n return;\n }\n\n this.iframe.postMessage(\"checkout:update-tokens\", { accessToken, refreshToken });\n }\n\n /**\n * Add an item to cart and open the cart drawer\n *\n * @param productId - Product ID (required)\n * @param variantId - Variant ID (required, null for non-variant products)\n * @param quantity - Quantity to add (default: 1)\n */\n addToCart(productId: string, variantId: string | null, quantity = 1): void {\n if (!this.isReady) {\n // biome-ignore lint/suspicious/noConsole: Intentional warning\n console.warn(\"[Commercengine] Not ready. Wait for onReady callback or 'ready' event.\");\n return;\n }\n\n this.iframe.postMessage(\"checkout:add-item\", {\n productId,\n variantId,\n quantity,\n });\n }\n\n /**\n * Get current cart state\n */\n getCart(): CartData {\n return { ...this.cartState };\n }\n\n /**\n * Check if checkout is ready\n */\n get ready(): boolean {\n return this.isReady;\n }\n\n /**\n * Check if checkout overlay is currently open\n */\n get open(): boolean {\n return this.isOpen;\n }\n\n /**\n * Subscribe to an event\n * @override EventEmitter.on with typed overloads\n */\n on(event: \"ready\", listener: EventListener<void>): void;\n on(event: \"open\", listener: EventListener<void>): void;\n on(event: \"close\", listener: EventListener<void>): void;\n on(event: \"complete\", listener: EventListener<OrderData>): void;\n on(event: \"cart:updated\", listener: EventListener<CartData>): void;\n on(event: \"auth:login\", listener: EventListener<AuthLoginData>): void;\n on(event: \"auth:logout\", listener: EventListener<AuthLogoutData>): void;\n on(event: \"auth:refresh\", listener: EventListener<AuthRefreshData>): void;\n on(event: \"auth:session-error\", listener: EventListener<void>): void;\n on<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void {\n super.on(event, listener);\n }\n\n /**\n * Destroy the checkout instance\n * Removes iframe and cleans up event listeners\n */\n destroy(): void {\n window.removeEventListener(\"message\", this.boundMessageHandler);\n this.iframe.destroy();\n this.removeAllListeners();\n this.isReady = false;\n this.isOpen = false;\n }\n}\n","/**\n * Commerce Engine Checkout\n *\n * @commercengine/js - Embeddable checkout SDK\n *\n * @example CDN Usage (Vanilla JS):\n * ```html\n * <script src=\"https://cdn.commercengine.com/v1.js\" async></script>\n * <script>\n * window.Commercengine.onLoad = async () => {\n * const checkout = await Commercengine.init({\n * storeId: \"store_xxx\",\n * apiKey: \"ak_xxx\",\n * theme: \"dark\",\n * onComplete: (order) => console.log(\"Order:\", order.orderNumber),\n * });\n *\n * document.getElementById(\"cart-btn\").onclick = () => checkout.openCart();\n * };\n * </script>\n * ```\n *\n * @example ESM Import:\n * ```typescript\n * import { Commercengine } from \"@commercengine/js\";\n *\n * const checkout = await Commercengine.init({\n * storeId: \"store_xxx\",\n * apiKey: \"ak_xxx\",\n * });\n *\n * checkout.on(\"cart:updated\", (cart) => updateBadge(cart.count));\n * checkout.openCart();\n * ```\n */\n\nimport { Checkout } from \"./checkout\";\nimport type { CheckoutConfig } from \"./types\";\n\n// Re-export types for consumers\nexport type {\n AddToCartItem,\n AuthLoginData,\n AuthLogoutData,\n AuthMode,\n AuthRefreshData,\n CartData,\n Channel,\n CheckoutConfig,\n CheckoutEventType,\n CheckoutFeatures,\n Environment,\n ErrorData,\n LoginMethod,\n OrderData,\n QuickBuyConfig,\n SessionMode,\n UserInfo,\n} from \"./types\";\n\nexport { Checkout };\n\n// =============================================================================\n// GLOBAL API\n// =============================================================================\n\n/**\n * Global Commercengine object interface\n */\ninterface CommercengineGlobal {\n /**\n * Initialize checkout with configuration\n * @returns Promise that resolves to Checkout instance\n */\n init: (config: CheckoutConfig) => Promise<Checkout>;\n\n /**\n * Callback invoked when script has loaded\n * Set this BEFORE including the script to be notified when ready\n */\n onLoad?: () => void;\n\n /**\n * Current checkout instance (if initialized)\n */\n instance?: Checkout;\n}\n\n/**\n * Global Commercengine namespace\n */\nconst Commercengine: CommercengineGlobal = {\n /**\n * Initialize checkout\n *\n * @param config - Checkout configuration\n * @returns Checkout instance\n *\n * @example\n * const checkout = await Commercengine.init({\n * storeId: \"store_xxx\",\n * apiKey: \"ak_xxx\",\n * theme: \"system\",\n * });\n */\n init: async (config: CheckoutConfig): Promise<Checkout> => {\n // Validate required fields - either url (for dev) or storeId+apiKey (for prod)\n if (!config.url && (!config.storeId || !config.apiKey)) {\n throw new Error(\n \"[Commercengine] Either 'url' or both 'storeId' and 'apiKey' must be provided\"\n );\n }\n\n // Destroy existing instance if any\n if (Commercengine.instance) {\n Commercengine.instance.destroy();\n }\n\n // Create new instance\n const checkout = new Checkout(config);\n Commercengine.instance = checkout;\n\n // Wait for ready or error with timeout\n return new Promise((resolve, reject) => {\n if (checkout.ready) {\n resolve(checkout);\n return;\n }\n\n const timeoutMs = 30000; // 30 second timeout\n const timeout = setTimeout(() => {\n reject(new Error(\"Checkout initialization timed out\"));\n }, timeoutMs);\n\n // Resolve on ready\n checkout.once(\"ready\", () => {\n clearTimeout(timeout);\n resolve(checkout);\n });\n\n // Also resolve on error (checkout is still usable, will show error drawer)\n checkout.once(\"error\", () => {\n clearTimeout(timeout);\n resolve(checkout);\n });\n });\n },\n};\n\n// =============================================================================\n// GLOBAL SETUP\n// =============================================================================\n\n// Expose on window for CDN usage\nif (typeof window !== \"undefined\") {\n // Preserve any existing onLoad callback set before script loaded\n const existingOnLoad = (window as unknown as { Commercengine?: CommercengineGlobal })\n .Commercengine?.onLoad;\n\n // Set global\n (window as unknown as { Commercengine: CommercengineGlobal }).Commercengine = Commercengine;\n\n // Restore and call onLoad if it was set\n if (existingOnLoad) {\n Commercengine.onLoad = existingOnLoad;\n try {\n existingOnLoad();\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: Intentional error logging\n console.error(\"[Commercengine] Error in onLoad callback:\", error);\n }\n }\n}\n\nexport { Commercengine };\nexport default Commercengine;\n"],"mappings":"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"}
|
package/dist/index.d.cts
DELETED
|
@@ -1,456 +0,0 @@
|
|
|
1
|
-
//#region src/types.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Commerce Engine Checkout - Type Definitions
|
|
4
|
-
*
|
|
5
|
-
* @commercengine/js
|
|
6
|
-
*
|
|
7
|
-
* This is the single source of truth for checkout configuration.
|
|
8
|
-
* The checkout app parses these from URL parameters.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Authentication mode
|
|
12
|
-
* - 'managed': Checkout manages token lifecycle (refresh, storage)
|
|
13
|
-
* - 'provided': Parent manages tokens. Checkout uses in-memory only, syncs via events
|
|
14
|
-
*/
|
|
15
|
-
type AuthMode = "managed" | "provided";
|
|
16
|
-
/**
|
|
17
|
-
* Item to add to cart
|
|
18
|
-
*/
|
|
19
|
-
interface AddToCartItem {
|
|
20
|
-
/**
|
|
21
|
-
* Product ID (required)
|
|
22
|
-
*/
|
|
23
|
-
productId: string;
|
|
24
|
-
/**
|
|
25
|
-
* Variant ID (required, null for non-variant products)
|
|
26
|
-
*/
|
|
27
|
-
variantId: string | null;
|
|
28
|
-
/**
|
|
29
|
-
* Quantity to add
|
|
30
|
-
* @default 1
|
|
31
|
-
*/
|
|
32
|
-
quantity?: number;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Quick buy configuration for initialization
|
|
36
|
-
* Adds a product to cart when checkout initializes
|
|
37
|
-
*/
|
|
38
|
-
interface QuickBuyConfig {
|
|
39
|
-
/**
|
|
40
|
-
* Product ID (required)
|
|
41
|
-
*/
|
|
42
|
-
productId: string;
|
|
43
|
-
/**
|
|
44
|
-
* Variant ID (required, null for non-variant products)
|
|
45
|
-
*/
|
|
46
|
-
variantId: string | null;
|
|
47
|
-
/**
|
|
48
|
-
* Quantity to add
|
|
49
|
-
* @default 1
|
|
50
|
-
*/
|
|
51
|
-
quantity?: number;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Session behavior mode
|
|
55
|
-
* - 'continue-existing': Add quick-buy item to existing cart (default)
|
|
56
|
-
* - 'force-new': Clear cart and start fresh
|
|
57
|
-
*/
|
|
58
|
-
type SessionMode = "continue-existing" | "force-new";
|
|
59
|
-
/**
|
|
60
|
-
* Feature flags for checkout
|
|
61
|
-
* All features are enabled by default
|
|
62
|
-
*/
|
|
63
|
-
interface CheckoutFeatures {
|
|
64
|
-
/**
|
|
65
|
-
* Enable loyalty points redemption
|
|
66
|
-
* @default true
|
|
67
|
-
*/
|
|
68
|
-
loyalty?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Enable coupon/promo codes
|
|
71
|
-
* @default true
|
|
72
|
-
*/
|
|
73
|
-
coupons?: boolean;
|
|
74
|
-
/**
|
|
75
|
-
* Enable collect-in-store option
|
|
76
|
-
* @default false
|
|
77
|
-
*/
|
|
78
|
-
collectInStore?: boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Enable free shipping progress tracker in cart
|
|
81
|
-
* @default true
|
|
82
|
-
*/
|
|
83
|
-
freeShippingProgress?: boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Enable product recommendations in cart
|
|
86
|
-
* @default true
|
|
87
|
-
*/
|
|
88
|
-
productRecommendations?: boolean;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Environment for checkout
|
|
92
|
-
* - 'production': Uses checkout.commercengine.com
|
|
93
|
-
* - 'staging': Uses checkout.staging.commercengine.com
|
|
94
|
-
*/
|
|
95
|
-
type Environment = "production" | "staging";
|
|
96
|
-
/**
|
|
97
|
-
* Configuration for initializing checkout
|
|
98
|
-
*
|
|
99
|
-
* Either provide `url` directly (for local development) or
|
|
100
|
-
* provide `storeId` + `apiKey` (for production).
|
|
101
|
-
*/
|
|
102
|
-
interface CheckoutConfig {
|
|
103
|
-
/**
|
|
104
|
-
* Environment to use for checkout URL resolution
|
|
105
|
-
* - 'production': checkout.commercengine.com (default)
|
|
106
|
-
* - 'staging': staging.checkout.commercengine.com
|
|
107
|
-
*
|
|
108
|
-
* For local development, use the `url` option instead.
|
|
109
|
-
*/
|
|
110
|
-
environment?: Environment;
|
|
111
|
-
/**
|
|
112
|
-
* Direct checkout URL (overrides environment detection)
|
|
113
|
-
* If provided, storeId and apiKey are optional.
|
|
114
|
-
* @example "http://localhost:8080"
|
|
115
|
-
*/
|
|
116
|
-
url?: string;
|
|
117
|
-
/**
|
|
118
|
-
* Your Commerce Engine Store ID
|
|
119
|
-
* Required if `url` is not provided.
|
|
120
|
-
* @example "store_abc123"
|
|
121
|
-
*/
|
|
122
|
-
storeId?: string;
|
|
123
|
-
/**
|
|
124
|
-
* Your Commerce Engine API Key
|
|
125
|
-
* Required if `url` is not provided.
|
|
126
|
-
* @example "ak_test_xyz789"
|
|
127
|
-
*/
|
|
128
|
-
apiKey?: string;
|
|
129
|
-
/**
|
|
130
|
-
* Theme preference
|
|
131
|
-
* @default "system"
|
|
132
|
-
*/
|
|
133
|
-
theme?: "light" | "dark" | "system";
|
|
134
|
-
/**
|
|
135
|
-
* Appearance customization
|
|
136
|
-
*/
|
|
137
|
-
appearance?: {
|
|
138
|
-
/**
|
|
139
|
-
* Z-index for the checkout overlay
|
|
140
|
-
* @default 99999
|
|
141
|
-
*/
|
|
142
|
-
zIndex?: number;
|
|
143
|
-
};
|
|
144
|
-
/**
|
|
145
|
-
* Authentication mode
|
|
146
|
-
* - 'managed': Checkout manages token lifecycle (default)
|
|
147
|
-
* - 'provided': Parent manages tokens, checkout uses in-memory only
|
|
148
|
-
* @default "managed"
|
|
149
|
-
*/
|
|
150
|
-
authMode?: AuthMode;
|
|
151
|
-
/**
|
|
152
|
-
* Initial access token (if user already logged in on parent site)
|
|
153
|
-
*/
|
|
154
|
-
accessToken?: string;
|
|
155
|
-
/**
|
|
156
|
-
* Initial refresh token
|
|
157
|
-
*/
|
|
158
|
-
refreshToken?: string;
|
|
159
|
-
/**
|
|
160
|
-
* Quick buy configuration for "Buy Now" flows
|
|
161
|
-
* When provided, adds the product to cart on initialization
|
|
162
|
-
*/
|
|
163
|
-
quickBuy?: QuickBuyConfig;
|
|
164
|
-
/**
|
|
165
|
-
* Session behavior when quick buy is used
|
|
166
|
-
* @default "continue-existing"
|
|
167
|
-
*/
|
|
168
|
-
sessionMode?: SessionMode;
|
|
169
|
-
/**
|
|
170
|
-
* Auto-detect quick buy params from parent page URL
|
|
171
|
-
* When enabled, SDK parses window.location.search for:
|
|
172
|
-
* - product_id, variant_id, qty/quantity, session_mode
|
|
173
|
-
* Useful for ad-driven traffic to embedded checkout pages
|
|
174
|
-
* @default false
|
|
175
|
-
*/
|
|
176
|
-
autoDetectQuickBuy?: boolean;
|
|
177
|
-
/**
|
|
178
|
-
* Feature flags to enable/disable checkout features
|
|
179
|
-
* All features are enabled by default
|
|
180
|
-
*/
|
|
181
|
-
features?: CheckoutFeatures;
|
|
182
|
-
/**
|
|
183
|
-
* Called when checkout iframe is loaded and ready
|
|
184
|
-
*/
|
|
185
|
-
onReady?: () => void;
|
|
186
|
-
/**
|
|
187
|
-
* Called when checkout drawer is opened
|
|
188
|
-
*/
|
|
189
|
-
onOpen?: () => void;
|
|
190
|
-
/**
|
|
191
|
-
* Called when checkout is closed (all drawers closed)
|
|
192
|
-
*/
|
|
193
|
-
onClose?: () => void;
|
|
194
|
-
/**
|
|
195
|
-
* Called when order is completed successfully
|
|
196
|
-
*/
|
|
197
|
-
onComplete?: (order: OrderData) => void;
|
|
198
|
-
/**
|
|
199
|
-
* Called when cart state changes (items added/removed/updated)
|
|
200
|
-
* Use this to update cart badge count on parent site
|
|
201
|
-
*/
|
|
202
|
-
onCartUpdate?: (cart: CartData) => void;
|
|
203
|
-
/**
|
|
204
|
-
* Called when user logs in via checkout
|
|
205
|
-
*/
|
|
206
|
-
onLogin?: (data: AuthLoginData) => void;
|
|
207
|
-
/**
|
|
208
|
-
* Called when user logs out (receives new anonymous tokens)
|
|
209
|
-
*/
|
|
210
|
-
onLogout?: (data: AuthLogoutData) => void;
|
|
211
|
-
/**
|
|
212
|
-
* Called when tokens are auto-refreshed by SDK
|
|
213
|
-
*/
|
|
214
|
-
onTokenRefresh?: (data: AuthRefreshData) => void;
|
|
215
|
-
/**
|
|
216
|
-
* Called when session is corrupted and SDK clears all tokens.
|
|
217
|
-
* User needs to re-authenticate.
|
|
218
|
-
*/
|
|
219
|
-
onSessionError?: () => void;
|
|
220
|
-
/**
|
|
221
|
-
* Called when checkout encounters a configuration error
|
|
222
|
-
* This happens when credentials are missing or invalid.
|
|
223
|
-
* The error drawer will still be shown, but you can use this
|
|
224
|
-
* callback to log the error or show custom UI.
|
|
225
|
-
*/
|
|
226
|
-
onError?: (error: ErrorData) => void;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Channel information from token
|
|
230
|
-
*/
|
|
231
|
-
interface Channel {
|
|
232
|
-
id: string;
|
|
233
|
-
name: string;
|
|
234
|
-
type: string;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* User information decoded from JWT token
|
|
238
|
-
* Matches @commercengine/storefront-sdk UserInfo 1:1
|
|
239
|
-
*/
|
|
240
|
-
interface UserInfo {
|
|
241
|
-
id: string;
|
|
242
|
-
email: string | null;
|
|
243
|
-
phone: string | null;
|
|
244
|
-
username: string;
|
|
245
|
-
firstName: string | null;
|
|
246
|
-
lastName: string | null;
|
|
247
|
-
storeId: string;
|
|
248
|
-
isLoggedIn: boolean;
|
|
249
|
-
isAnonymous: boolean;
|
|
250
|
-
customerId: string | null;
|
|
251
|
-
customerGroupId: string | null;
|
|
252
|
-
anonymousId: string;
|
|
253
|
-
channel: Channel;
|
|
254
|
-
tokenExpiry: Date;
|
|
255
|
-
tokenIssuedAt: Date;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Login method used for authentication
|
|
259
|
-
*/
|
|
260
|
-
type LoginMethod = "whatsapp" | "phone" | "email";
|
|
261
|
-
/**
|
|
262
|
-
* Cart state data emitted on cart:updated event
|
|
263
|
-
*/
|
|
264
|
-
interface CartData {
|
|
265
|
-
/** Number of items in cart */
|
|
266
|
-
count: number;
|
|
267
|
-
/** Cart subtotal amount */
|
|
268
|
-
total: number;
|
|
269
|
-
/** Currency code (e.g., "INR", "USD") */
|
|
270
|
-
currency: string;
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Order data emitted on checkout:complete event
|
|
274
|
-
*/
|
|
275
|
-
interface OrderData {
|
|
276
|
-
/** Order ID */
|
|
277
|
-
id: string;
|
|
278
|
-
/** Human-readable order number */
|
|
279
|
-
orderNumber: string;
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Data emitted on login event
|
|
283
|
-
*/
|
|
284
|
-
interface AuthLoginData {
|
|
285
|
-
accessToken: string;
|
|
286
|
-
refreshToken?: string;
|
|
287
|
-
user?: UserInfo;
|
|
288
|
-
loginMethod?: LoginMethod;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Data emitted on logout event
|
|
292
|
-
*/
|
|
293
|
-
interface AuthLogoutData {
|
|
294
|
-
accessToken: string;
|
|
295
|
-
refreshToken?: string;
|
|
296
|
-
user?: UserInfo;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Data emitted on token refresh event
|
|
300
|
-
*/
|
|
301
|
-
interface AuthRefreshData {
|
|
302
|
-
accessToken: string;
|
|
303
|
-
refreshToken?: string;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Error data emitted on checkout:error event
|
|
307
|
-
*/
|
|
308
|
-
interface ErrorData {
|
|
309
|
-
/** Error message */
|
|
310
|
-
message: string;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Events emitted by checkout
|
|
314
|
-
*/
|
|
315
|
-
type CheckoutEventType = "ready" | "open" | "close" | "complete" | "error" | "cart:updated" | "auth:login" | "auth:logout" | "auth:refresh" | "auth:session-error";
|
|
316
|
-
/**
|
|
317
|
-
* Event listener function type
|
|
318
|
-
*/
|
|
319
|
-
type EventListener<T = unknown> = (data: T) => void;
|
|
320
|
-
//#endregion
|
|
321
|
-
//#region src/events.d.ts
|
|
322
|
-
declare class EventEmitter {
|
|
323
|
-
private listeners;
|
|
324
|
-
/**
|
|
325
|
-
* Subscribe to an event
|
|
326
|
-
*/
|
|
327
|
-
on<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void;
|
|
328
|
-
/**
|
|
329
|
-
* Unsubscribe from an event
|
|
330
|
-
*/
|
|
331
|
-
off<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void;
|
|
332
|
-
/**
|
|
333
|
-
* Subscribe to an event (once)
|
|
334
|
-
*/
|
|
335
|
-
once<T = unknown>(event: CheckoutEventType, listener: EventListener<T>): void;
|
|
336
|
-
/**
|
|
337
|
-
* Emit an event to all subscribers
|
|
338
|
-
*/
|
|
339
|
-
protected emit<T = unknown>(event: CheckoutEventType, data?: T): void;
|
|
340
|
-
/**
|
|
341
|
-
* Remove all listeners
|
|
342
|
-
*/
|
|
343
|
-
protected removeAllListeners(): void;
|
|
344
|
-
}
|
|
345
|
-
//#endregion
|
|
346
|
-
//#region src/checkout.d.ts
|
|
347
|
-
declare class Checkout extends EventEmitter {
|
|
348
|
-
private config;
|
|
349
|
-
private iframe;
|
|
350
|
-
private isReady;
|
|
351
|
-
private isOpen;
|
|
352
|
-
private cartState;
|
|
353
|
-
private boundMessageHandler;
|
|
354
|
-
private hasQuickBuyParams;
|
|
355
|
-
constructor(config: CheckoutConfig);
|
|
356
|
-
private initialize;
|
|
357
|
-
/**
|
|
358
|
-
* Remove quick buy params from the parent URL to prevent duplicate adds on refresh
|
|
359
|
-
* Uses replaceState to avoid adding to browser history
|
|
360
|
-
*/
|
|
361
|
-
private cleanQuickBuyParamsFromUrl;
|
|
362
|
-
private handleMessage;
|
|
363
|
-
private handleReady;
|
|
364
|
-
private handleError;
|
|
365
|
-
private handleOpen;
|
|
366
|
-
private handleClose;
|
|
367
|
-
private handleComplete;
|
|
368
|
-
private handleCartUpdate;
|
|
369
|
-
private handleLogin;
|
|
370
|
-
private handleLogout;
|
|
371
|
-
private handleTokenRefresh;
|
|
372
|
-
private handleSessionError;
|
|
373
|
-
/**
|
|
374
|
-
* Open the cart drawer
|
|
375
|
-
*/
|
|
376
|
-
openCart(): void;
|
|
377
|
-
/**
|
|
378
|
-
* Open the checkout drawer directly (e.g., for Buy Now flow)
|
|
379
|
-
*/
|
|
380
|
-
openCheckout(): void;
|
|
381
|
-
/**
|
|
382
|
-
* Close the checkout overlay
|
|
383
|
-
*/
|
|
384
|
-
close(): void;
|
|
385
|
-
/**
|
|
386
|
-
* Update authentication tokens
|
|
387
|
-
* Use this when user logs in/out on the parent site
|
|
388
|
-
*/
|
|
389
|
-
updateTokens(accessToken: string, refreshToken?: string): void;
|
|
390
|
-
/**
|
|
391
|
-
* Add an item to cart and open the cart drawer
|
|
392
|
-
*
|
|
393
|
-
* @param productId - Product ID (required)
|
|
394
|
-
* @param variantId - Variant ID (required, null for non-variant products)
|
|
395
|
-
* @param quantity - Quantity to add (default: 1)
|
|
396
|
-
*/
|
|
397
|
-
addToCart(productId: string, variantId: string | null, quantity?: number): void;
|
|
398
|
-
/**
|
|
399
|
-
* Get current cart state
|
|
400
|
-
*/
|
|
401
|
-
getCart(): CartData;
|
|
402
|
-
/**
|
|
403
|
-
* Check if checkout is ready
|
|
404
|
-
*/
|
|
405
|
-
get ready(): boolean;
|
|
406
|
-
/**
|
|
407
|
-
* Check if checkout overlay is currently open
|
|
408
|
-
*/
|
|
409
|
-
get open(): boolean;
|
|
410
|
-
/**
|
|
411
|
-
* Subscribe to an event
|
|
412
|
-
* @override EventEmitter.on with typed overloads
|
|
413
|
-
*/
|
|
414
|
-
on(event: "ready", listener: EventListener<void>): void;
|
|
415
|
-
on(event: "open", listener: EventListener<void>): void;
|
|
416
|
-
on(event: "close", listener: EventListener<void>): void;
|
|
417
|
-
on(event: "complete", listener: EventListener<OrderData>): void;
|
|
418
|
-
on(event: "cart:updated", listener: EventListener<CartData>): void;
|
|
419
|
-
on(event: "auth:login", listener: EventListener<AuthLoginData>): void;
|
|
420
|
-
on(event: "auth:logout", listener: EventListener<AuthLogoutData>): void;
|
|
421
|
-
on(event: "auth:refresh", listener: EventListener<AuthRefreshData>): void;
|
|
422
|
-
on(event: "auth:session-error", listener: EventListener<void>): void;
|
|
423
|
-
/**
|
|
424
|
-
* Destroy the checkout instance
|
|
425
|
-
* Removes iframe and cleans up event listeners
|
|
426
|
-
*/
|
|
427
|
-
destroy(): void;
|
|
428
|
-
}
|
|
429
|
-
//#endregion
|
|
430
|
-
//#region src/index.d.ts
|
|
431
|
-
/**
|
|
432
|
-
* Global Commercengine object interface
|
|
433
|
-
*/
|
|
434
|
-
interface CommercengineGlobal {
|
|
435
|
-
/**
|
|
436
|
-
* Initialize checkout with configuration
|
|
437
|
-
* @returns Promise that resolves to Checkout instance
|
|
438
|
-
*/
|
|
439
|
-
init: (config: CheckoutConfig) => Promise<Checkout>;
|
|
440
|
-
/**
|
|
441
|
-
* Callback invoked when script has loaded
|
|
442
|
-
* Set this BEFORE including the script to be notified when ready
|
|
443
|
-
*/
|
|
444
|
-
onLoad?: () => void;
|
|
445
|
-
/**
|
|
446
|
-
* Current checkout instance (if initialized)
|
|
447
|
-
*/
|
|
448
|
-
instance?: Checkout;
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Global Commercengine namespace
|
|
452
|
-
*/
|
|
453
|
-
declare const Commercengine: CommercengineGlobal;
|
|
454
|
-
//#endregion
|
|
455
|
-
export { type AddToCartItem, type AuthLoginData, type AuthLogoutData, type AuthMode, type AuthRefreshData, type CartData, type Channel, Checkout, type CheckoutConfig, type CheckoutEventType, type CheckoutFeatures, Commercengine, Commercengine as default, type Environment, type ErrorData, type LoginMethod, type OrderData, type QuickBuyConfig, type SessionMode, type UserInfo };
|
|
456
|
-
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/events.ts","../src/checkout.ts","../src/index.ts"],"mappings":"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"}
|