@tagadapay/headless-sdk 1.0.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 (79) hide show
  1. package/README.md +110 -0
  2. package/dist/core/client.d.ts +48 -0
  3. package/dist/core/client.d.ts.map +1 -0
  4. package/dist/core/client.js +61 -0
  5. package/dist/core/client.js.map +1 -0
  6. package/dist/core/errors.d.ts +46 -0
  7. package/dist/core/errors.d.ts.map +1 -0
  8. package/dist/core/errors.js +57 -0
  9. package/dist/core/errors.js.map +1 -0
  10. package/dist/core/http.d.ts +27 -0
  11. package/dist/core/http.d.ts.map +1 -0
  12. package/dist/core/http.js +116 -0
  13. package/dist/core/http.js.map +1 -0
  14. package/dist/core/index.d.ts +10 -0
  15. package/dist/core/index.d.ts.map +1 -0
  16. package/dist/core/index.js +9 -0
  17. package/dist/core/index.js.map +1 -0
  18. package/dist/core/modules/analytics.d.ts +79 -0
  19. package/dist/core/modules/analytics.d.ts.map +1 -0
  20. package/dist/core/modules/analytics.js +265 -0
  21. package/dist/core/modules/analytics.js.map +1 -0
  22. package/dist/core/modules/checkout.d.ts +67 -0
  23. package/dist/core/modules/checkout.d.ts.map +1 -0
  24. package/dist/core/modules/checkout.js +164 -0
  25. package/dist/core/modules/checkout.js.map +1 -0
  26. package/dist/core/modules/customer.d.ts +33 -0
  27. package/dist/core/modules/customer.d.ts.map +1 -0
  28. package/dist/core/modules/customer.js +53 -0
  29. package/dist/core/modules/customer.js.map +1 -0
  30. package/dist/core/modules/offers.d.ts +43 -0
  31. package/dist/core/modules/offers.d.ts.map +1 -0
  32. package/dist/core/modules/offers.js +56 -0
  33. package/dist/core/modules/offers.js.map +1 -0
  34. package/dist/core/modules/payment.d.ts +123 -0
  35. package/dist/core/modules/payment.d.ts.map +1 -0
  36. package/dist/core/modules/payment.js +279 -0
  37. package/dist/core/modules/payment.js.map +1 -0
  38. package/dist/core/types.d.ts +276 -0
  39. package/dist/core/types.d.ts.map +1 -0
  40. package/dist/core/types.js +5 -0
  41. package/dist/core/types.js.map +1 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +2 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/react/hooks/useAnalytics.d.ts +59 -0
  47. package/dist/react/hooks/useAnalytics.d.ts.map +1 -0
  48. package/dist/react/hooks/useAnalytics.js +49 -0
  49. package/dist/react/hooks/useAnalytics.js.map +1 -0
  50. package/dist/react/hooks/useCheckout.d.ts +45 -0
  51. package/dist/react/hooks/useCheckout.d.ts.map +1 -0
  52. package/dist/react/hooks/useCheckout.js +113 -0
  53. package/dist/react/hooks/useCheckout.js.map +1 -0
  54. package/dist/react/hooks/useCustomer.d.ts +28 -0
  55. package/dist/react/hooks/useCustomer.d.ts.map +1 -0
  56. package/dist/react/hooks/useCustomer.js +77 -0
  57. package/dist/react/hooks/useCustomer.js.map +1 -0
  58. package/dist/react/hooks/useOffers.d.ts +45 -0
  59. package/dist/react/hooks/useOffers.d.ts.map +1 -0
  60. package/dist/react/hooks/useOffers.js +88 -0
  61. package/dist/react/hooks/useOffers.js.map +1 -0
  62. package/dist/react/hooks/usePayment.d.ts +63 -0
  63. package/dist/react/hooks/usePayment.d.ts.map +1 -0
  64. package/dist/react/hooks/usePayment.js +114 -0
  65. package/dist/react/hooks/usePayment.js.map +1 -0
  66. package/dist/react/index.d.ts +14 -0
  67. package/dist/react/index.d.ts.map +1 -0
  68. package/dist/react/index.js +7 -0
  69. package/dist/react/index.js.map +1 -0
  70. package/dist/react/provider.d.ts +31 -0
  71. package/dist/react/provider.d.ts.map +1 -0
  72. package/dist/react/provider.js +32 -0
  73. package/dist/react/provider.js.map +1 -0
  74. package/dist/tagada-headless-react.min.js +8 -0
  75. package/dist/tagada-headless-react.min.js.map +7 -0
  76. package/dist/tagada-headless.js +1093 -0
  77. package/dist/tagada-headless.min.js +8 -0
  78. package/dist/tagada-headless.min.js.map +7 -0
  79. package/package.json +72 -0
@@ -0,0 +1,1093 @@
1
+ /**
2
+ * @tagadapay/headless-sdk v1.0.0
3
+ * Headless checkout, payments, analytics, and CRM
4
+ * @license MIT
5
+ */
6
+ "use strict";
7
+ var TagadaHeadlessBundle = (() => {
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
15
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
16
+ }) : x)(function(x) {
17
+ if (typeof require !== "undefined")
18
+ return require.apply(this, arguments);
19
+ throw Error('Dynamic require of "' + x + '" is not supported');
20
+ });
21
+ var __export = (target, all) => {
22
+ for (var name in all)
23
+ __defProp(target, name, { get: all[name], enumerable: true });
24
+ };
25
+ var __copyProps = (to, from, except, desc) => {
26
+ if (from && typeof from === "object" || typeof from === "function") {
27
+ for (let key of __getOwnPropNames(from))
28
+ if (!__hasOwnProp.call(to, key) && key !== except)
29
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
30
+ }
31
+ return to;
32
+ };
33
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
34
+ // If the importer is in node compatibility mode or this is not an ESM
35
+ // file that has been converted to a CommonJS file using a Babel-
36
+ // compatible transform (i.e. "__esModule" has not been set), then set
37
+ // "default" to the CommonJS "module.exports" for node compatibility.
38
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
39
+ mod
40
+ ));
41
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
42
+
43
+ // src/core/index.ts
44
+ var core_exports = {};
45
+ __export(core_exports, {
46
+ AnalyticsModule: () => AnalyticsModule,
47
+ CheckoutModule: () => CheckoutModule,
48
+ CustomerModule: () => CustomerModule,
49
+ HeadlessClient: () => HeadlessClient,
50
+ HttpClient: () => HttpClient,
51
+ OffersModule: () => OffersModule,
52
+ PaymentModule: () => PaymentModule,
53
+ TagadaAuthError: () => TagadaAuthError,
54
+ TagadaError: () => TagadaError,
55
+ TagadaNetworkError: () => TagadaNetworkError,
56
+ TagadaNotFoundError: () => TagadaNotFoundError,
57
+ TagadaPaymentError: () => TagadaPaymentError,
58
+ TagadaRateLimitError: () => TagadaRateLimitError,
59
+ TagadaValidationError: () => TagadaValidationError,
60
+ createHeadlessClient: () => createHeadlessClient
61
+ });
62
+
63
+ // src/core/errors.ts
64
+ var TagadaError = class extends Error {
65
+ constructor(message, code, statusCode, details) {
66
+ super(message);
67
+ this.name = "TagadaError";
68
+ this.code = code;
69
+ this.statusCode = statusCode;
70
+ this.details = details;
71
+ }
72
+ };
73
+ var TagadaAuthError = class extends TagadaError {
74
+ constructor(message = "Authentication failed. Check your API key or checkout token.") {
75
+ super(message, "auth_error", 401);
76
+ this.name = "TagadaAuthError";
77
+ }
78
+ };
79
+ var TagadaValidationError = class extends TagadaError {
80
+ constructor(message, errors = []) {
81
+ super(message, "validation_error", 422, { errors });
82
+ this.name = "TagadaValidationError";
83
+ this.errors = errors;
84
+ }
85
+ };
86
+ var TagadaNotFoundError = class extends TagadaError {
87
+ constructor(resource, id) {
88
+ super(`${resource} "${id}" not found.`, "not_found", 404);
89
+ this.name = "TagadaNotFoundError";
90
+ }
91
+ };
92
+ var TagadaRateLimitError = class extends TagadaError {
93
+ constructor(retryAfterMs = 1e3) {
94
+ super(`Rate limited. Retry after ${retryAfterMs}ms.`, "rate_limit", 429);
95
+ this.name = "TagadaRateLimitError";
96
+ this.retryAfterMs = retryAfterMs;
97
+ }
98
+ };
99
+ var TagadaPaymentError = class extends TagadaError {
100
+ constructor(message, opts) {
101
+ super(message, "payment_error", void 0, opts == null ? void 0 : opts.details);
102
+ this.name = "TagadaPaymentError";
103
+ this.paymentId = opts == null ? void 0 : opts.paymentId;
104
+ this.requireAction = opts == null ? void 0 : opts.requireAction;
105
+ }
106
+ };
107
+ var TagadaNetworkError = class extends TagadaError {
108
+ constructor(message = "Network request failed. Check your connection.") {
109
+ super(message, "network_error");
110
+ this.name = "TagadaNetworkError";
111
+ }
112
+ };
113
+
114
+ // src/core/http.ts
115
+ var BASE_URLS = {
116
+ production: "https://app.tagadapay.com",
117
+ development: "https://app.dev.tagadapay.com",
118
+ local: "http://localhost:3000"
119
+ };
120
+ var HttpClient = class {
121
+ constructor(config) {
122
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
123
+ this.timeout = config.timeout;
124
+ this.apiKey = config.apiKey;
125
+ this.getToken = config.getToken;
126
+ }
127
+ static resolveBaseUrl(environment, override) {
128
+ return override ?? BASE_URLS[environment] ?? BASE_URLS.production;
129
+ }
130
+ async request(path, options = {}) {
131
+ var _a;
132
+ const { method = "GET", body, headers = {}, params, token, signal } = options;
133
+ let url = `${this.baseUrl}${path}`;
134
+ if (params) {
135
+ const qs = new URLSearchParams();
136
+ for (const [k, v] of Object.entries(params)) {
137
+ if (v !== void 0)
138
+ qs.set(k, String(v));
139
+ }
140
+ const str = qs.toString();
141
+ if (str)
142
+ url += `?${str}`;
143
+ }
144
+ const reqHeaders = {
145
+ "Content-Type": "application/json",
146
+ ...headers
147
+ };
148
+ const authToken = token ?? this.apiKey ?? ((_a = this.getToken) == null ? void 0 : _a.call(this));
149
+ if (authToken) {
150
+ reqHeaders["x-cms-token"] = authToken;
151
+ }
152
+ const controller = new AbortController();
153
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
154
+ try {
155
+ const res = await fetch(url, {
156
+ method,
157
+ headers: reqHeaders,
158
+ body: body != null ? JSON.stringify(body) : void 0,
159
+ signal: signal ?? controller.signal
160
+ });
161
+ clearTimeout(timeoutId);
162
+ if (res.ok) {
163
+ const text = await res.text();
164
+ return text ? JSON.parse(text) : {};
165
+ }
166
+ await this.handleErrorResponse(res, path);
167
+ throw new TagadaError("Unexpected error", "unknown", res.status);
168
+ } catch (err) {
169
+ clearTimeout(timeoutId);
170
+ if (err instanceof TagadaError)
171
+ throw err;
172
+ if (err instanceof DOMException && err.name === "AbortError") {
173
+ throw new TagadaNetworkError(`Request to ${path} timed out after ${this.timeout}ms.`);
174
+ }
175
+ throw new TagadaNetworkError(
176
+ err instanceof Error ? err.message : "Network request failed."
177
+ );
178
+ }
179
+ }
180
+ get(path, options) {
181
+ return this.request(path, { ...options, method: "GET" });
182
+ }
183
+ post(path, body, options) {
184
+ return this.request(path, { ...options, method: "POST", body });
185
+ }
186
+ patch(path, body, options) {
187
+ return this.request(path, { ...options, method: "PATCH", body });
188
+ }
189
+ put(path, body, options) {
190
+ return this.request(path, { ...options, method: "PUT", body });
191
+ }
192
+ delete(path, options) {
193
+ return this.request(path, { ...options, method: "DELETE" });
194
+ }
195
+ async handleErrorResponse(res, path) {
196
+ let parsed = {};
197
+ try {
198
+ parsed = await res.json();
199
+ } catch {
200
+ }
201
+ const msg = parsed.message ?? parsed.error ?? `Request failed: ${res.status} ${res.statusText} on ${path}`;
202
+ switch (res.status) {
203
+ case 401:
204
+ case 403:
205
+ throw new TagadaAuthError(msg);
206
+ case 404:
207
+ throw new TagadaNotFoundError(path, "");
208
+ case 422: {
209
+ const fieldErrors = Array.isArray(parsed.errors) ? parsed.errors : [];
210
+ throw new TagadaValidationError(msg, fieldErrors);
211
+ }
212
+ case 429: {
213
+ const retryAfter = Number(res.headers.get("Retry-After") ?? "1") * 1e3;
214
+ throw new TagadaRateLimitError(retryAfter);
215
+ }
216
+ default:
217
+ throw new TagadaError(msg, "api_error", res.status, parsed);
218
+ }
219
+ }
220
+ };
221
+
222
+ // src/core/modules/checkout.ts
223
+ var CheckoutModule = class {
224
+ constructor(http, storeId, onTokenChange) {
225
+ this.http = http;
226
+ this.storeId = storeId;
227
+ this.onTokenChange = onTokenChange;
228
+ }
229
+ /**
230
+ * Load an existing checkout session by its checkout token.
231
+ *
232
+ * @param checkoutToken The checkout token (from URL param `checkoutToken`).
233
+ * @param sessionToken The JWT session token (from URL param `token`). Required for auth.
234
+ *
235
+ * Both values come from the redirect URL returned by `createSession()`.
236
+ * Example URL: `/checkout?checkoutToken=abc123&token=eyJ...`
237
+ */
238
+ async loadSession(checkoutToken, sessionToken) {
239
+ var _a;
240
+ if (sessionToken) {
241
+ this.sessionToken = sessionToken;
242
+ (_a = this.onTokenChange) == null ? void 0 : _a.call(this, sessionToken);
243
+ }
244
+ const raw = await this.http.get(
245
+ `/api/v1/checkout-sessions/${checkoutToken}/v2`,
246
+ {
247
+ params: { skipAsyncWait: "false" },
248
+ token: this.sessionToken
249
+ }
250
+ );
251
+ return this.normalizeSession(raw);
252
+ }
253
+ /**
254
+ * Create a new checkout session.
255
+ *
256
+ * Returns a `checkoutToken` and `sessionToken` (JWT) needed for all subsequent calls.
257
+ * Also returns a `checkoutUrl` (the full Tagada-hosted checkout URL, for reference).
258
+ */
259
+ async createSession(opts) {
260
+ var _a;
261
+ const lineItems = opts.items.map((i) => ({
262
+ variantId: i.variantId,
263
+ priceId: i.priceId,
264
+ quantity: i.quantity
265
+ }));
266
+ const body = {
267
+ storeId: this.storeId,
268
+ lineItems
269
+ };
270
+ if (opts.currency)
271
+ body.currency = opts.currency;
272
+ if (opts.returnUrl)
273
+ body.returnUrl = opts.returnUrl;
274
+ if (opts.customerEmail) {
275
+ body.customer = {
276
+ email: opts.customerEmail,
277
+ firstName: opts.customerFirstName,
278
+ lastName: opts.customerLastName,
279
+ currency: opts.currency
280
+ };
281
+ }
282
+ const res = await this.http.post("/api/v1/checkout/session/init", body);
283
+ const url = new URL(res.checkoutUrl);
284
+ const sessionToken = url.searchParams.get("token") ?? "";
285
+ this.sessionToken = sessionToken;
286
+ if (sessionToken)
287
+ (_a = this.onTokenChange) == null ? void 0 : _a.call(this, sessionToken);
288
+ return {
289
+ checkoutUrl: res.checkoutUrl,
290
+ checkoutToken: res.checkoutToken,
291
+ sessionToken,
292
+ customerId: res.customerId
293
+ };
294
+ }
295
+ /** Replace the cart items for an existing session. */
296
+ async updateCart(sessionId, items) {
297
+ return this.http.post(
298
+ `/api/v1/checkout-sessions/${sessionId}/items`,
299
+ { items },
300
+ { token: this.sessionToken }
301
+ );
302
+ }
303
+ /** Update customer information on the session. */
304
+ async updateCustomer(sessionId, customer) {
305
+ return this.http.patch(
306
+ `/api/v1/checkout-sessions/${sessionId}/customer`,
307
+ { data: customer },
308
+ { token: this.sessionToken }
309
+ );
310
+ }
311
+ /** Update shipping and/or billing address on the session. */
312
+ async updateAddress(sessionId, addresses) {
313
+ return this.http.post(
314
+ `/api/v1/checkout-sessions/${sessionId}/address`,
315
+ { data: addresses },
316
+ { token: this.sessionToken }
317
+ );
318
+ }
319
+ /** Apply a promotion code to the session. */
320
+ async applyPromoCode(sessionId, code) {
321
+ return this.http.post(
322
+ `/api/v1/checkout-sessions/${sessionId}/promo`,
323
+ { code },
324
+ { token: this.sessionToken }
325
+ );
326
+ }
327
+ /** Remove the currently applied promotion code. */
328
+ async removePromoCode(sessionId) {
329
+ return this.http.delete(`/api/v1/checkout-sessions/${sessionId}/promo`, {
330
+ token: this.sessionToken
331
+ });
332
+ }
333
+ /** Fetch available shipping rates for the session's address. */
334
+ async getShippingRates(sessionId) {
335
+ const res = await this.http.get(
336
+ `/api/v1/checkout-sessions/${sessionId}/shipping-rates`,
337
+ { token: this.sessionToken }
338
+ );
339
+ return res.rates;
340
+ }
341
+ /** Select a shipping rate for the session. */
342
+ async selectShippingRate(sessionId, rateId) {
343
+ return this.http.post(
344
+ `/api/v1/checkout-sessions/${sessionId}/shipping-rates`,
345
+ { rateId },
346
+ { token: this.sessionToken }
347
+ );
348
+ }
349
+ /**
350
+ * Normalize the raw v2 API response into a cleaner CheckoutSession shape.
351
+ * The raw response has nested `checkoutSession` + `summary` -- we flatten it.
352
+ */
353
+ normalizeSession(raw) {
354
+ const cs = raw.checkoutSession;
355
+ const orderSummaries = cs.orderSummaries ?? [];
356
+ const summary = raw.summary ?? cs.summary ?? orderSummaries[0] ?? {};
357
+ const lineItems = cs.sessionLineItems ?? [];
358
+ const customer = cs.customer;
359
+ const items = lineItems.map((li) => {
360
+ const price = li.price;
361
+ const variant = (price == null ? void 0 : price.variant) ?? {};
362
+ const product = variant.product ?? {};
363
+ const currencyOpts = (price == null ? void 0 : price.currencyOptions) ?? {};
364
+ const usd = currencyOpts.USD ?? currencyOpts[Object.keys(currencyOpts)[0]];
365
+ return {
366
+ id: li.id,
367
+ variantId: li.variantId,
368
+ priceId: li.priceId,
369
+ productName: product.name ?? "",
370
+ variantName: variant.name ?? "",
371
+ quantity: li.quantity ?? 1,
372
+ unitAmount: (usd == null ? void 0 : usd.amount) ?? 0,
373
+ totalAmount: ((usd == null ? void 0 : usd.amount) ?? 0) * (li.quantity ?? 1),
374
+ currency: cs.selectedPresentmentCurrency ?? "USD",
375
+ imageUrl: variant.imageUrl ?? ""
376
+ };
377
+ });
378
+ const summaryItems = summary.items ?? [];
379
+ return {
380
+ id: cs.id,
381
+ storeId: cs.storeId,
382
+ checkoutToken: cs.checkoutToken,
383
+ currency: cs.selectedPresentmentCurrency ?? "USD",
384
+ items,
385
+ totals: {
386
+ subtotal: summary.subtotalAmount ?? 0,
387
+ discount: summary.totalPromotionAmount ?? 0,
388
+ shipping: summary.shippingCost ?? 0,
389
+ tax: summary.totalTaxAmount ?? 0,
390
+ total: summary.totalAmount ?? summaryItems.reduce((s, i) => s + (i.amount ?? 0), 0),
391
+ currency: summary.currency ?? cs.selectedPresentmentCurrency ?? "USD"
392
+ },
393
+ customer: customer ? {
394
+ id: customer.id,
395
+ email: customer.email,
396
+ firstName: customer.firstName,
397
+ lastName: customer.lastName
398
+ } : void 0,
399
+ shippingAddress: cs.shippingAddress,
400
+ billingAddress: cs.billingAddress,
401
+ metadata: cs.metadata
402
+ };
403
+ }
404
+ };
405
+
406
+ // src/core/modules/payment.ts
407
+ var PaymentModule = class {
408
+ constructor(http, storeId, environment) {
409
+ this.http = http;
410
+ this.storeId = storeId;
411
+ this.environment = environment;
412
+ }
413
+ // ---------------------------------------------------------------------------
414
+ // Discovery: what payment methods are available?
415
+ // ---------------------------------------------------------------------------
416
+ /**
417
+ * Get the full payment setup config for a checkout session.
418
+ * Returns a map of payment methods with their configuration
419
+ * (card, apple_pay, google_pay, klarna, etc.).
420
+ */
421
+ async getPaymentSetup(checkoutSessionId) {
422
+ const methods = await this.http.get(
423
+ "/api/v1/payment-methods",
424
+ { params: { checkoutSessionId } }
425
+ );
426
+ const config = {};
427
+ for (const m of methods.methods ?? []) {
428
+ const key = m.provider ? `${m.method}:${m.provider}` : m.method;
429
+ config[key] = m;
430
+ }
431
+ return config;
432
+ }
433
+ /**
434
+ * Get express payment methods (Apple Pay, Google Pay, PayPal, etc.)
435
+ * filtered to only those available in the current browser.
436
+ */
437
+ async getExpressMethods(checkoutSessionId) {
438
+ var _a, _b;
439
+ const setup = await this.getPaymentSetup(checkoutSessionId);
440
+ const result = {};
441
+ for (const [, config] of Object.entries(setup)) {
442
+ if (!config.enabled || !config.express)
443
+ continue;
444
+ const method = config.method;
445
+ const base = {
446
+ type: method,
447
+ available: true,
448
+ processorId: config.processorId,
449
+ publishableKey: config.publishableKey,
450
+ metadata: config.metadata
451
+ };
452
+ if (method === "apple_pay" || config.type === "apple_pay") {
453
+ const hasApplePay = typeof window !== "undefined" && "ApplePaySession" in window && ((_b = (_a = window.ApplePaySession) == null ? void 0 : _a.canMakePayments) == null ? void 0 : _b.call(_a));
454
+ result.applePay = { ...base, available: !!hasApplePay };
455
+ } else if (method === "google_pay" || config.type === "google_pay") {
456
+ result.googlePay = base;
457
+ } else if (method === "paypal") {
458
+ result.paypal = base;
459
+ } else if (method === "klarna" || method === "klarna_express") {
460
+ result.klarna = base;
461
+ } else if (method === "link") {
462
+ result.link = base;
463
+ }
464
+ }
465
+ return result;
466
+ }
467
+ /**
468
+ * Get store-level payment config (3DS flags, default flow ID, etc.).
469
+ */
470
+ async getStoreConfig() {
471
+ const res = await this.http.get(
472
+ "/api/v1/checkout/config",
473
+ { params: { storeId: this.storeId } }
474
+ );
475
+ return res.config ?? res;
476
+ }
477
+ /**
478
+ * Convenience: return only enabled payment method keys.
479
+ */
480
+ async getEnabledMethods(checkoutSessionId) {
481
+ const setup = await this.getPaymentSetup(checkoutSessionId);
482
+ return Object.entries(setup).filter(([, c]) => c.enabled).map(([key]) => key);
483
+ }
484
+ // ---------------------------------------------------------------------------
485
+ // Tokenization (delegates to @tagadapay/core-js if available)
486
+ // ---------------------------------------------------------------------------
487
+ /**
488
+ * Tokenize a card using @tagadapay/core-js.
489
+ * Requires `@tagadapay/core-js` to be installed as a peer dependency.
490
+ *
491
+ * @returns tagadaToken (base64 string) and rawToken with SCA metadata.
492
+ */
493
+ async tokenizeCard(card) {
494
+ const coreJs = await this.loadCoreJs();
495
+ const tokenizer = new coreJs.Tokenizer({ environment: this.environment });
496
+ await tokenizer.initialize();
497
+ const sanitized = {
498
+ cardNumber: card.cardNumber,
499
+ expiryDate: card.expiryDate,
500
+ cvc: card.cvc
501
+ };
502
+ if (card.cardholderName)
503
+ sanitized.cardholderName = card.cardholderName;
504
+ const [tagadaToken, rawToken] = await Promise.all([
505
+ tokenizer.tokenizeCard(sanitized),
506
+ tokenizer.tokenizeCardRaw(sanitized)
507
+ ]);
508
+ return { tagadaToken, rawToken };
509
+ }
510
+ // ---------------------------------------------------------------------------
511
+ // Instrument creation
512
+ // ---------------------------------------------------------------------------
513
+ /**
514
+ * Create a reusable payment instrument from a TagadaToken.
515
+ * Session-authenticated (uses the checkout session JWT).
516
+ */
517
+ async createInstrument(opts) {
518
+ return this.http.post("/api/v1/payment/create-instrument-from-token", {
519
+ tagadaToken: opts.tagadaToken
520
+ });
521
+ }
522
+ // ---------------------------------------------------------------------------
523
+ // 3DS
524
+ // ---------------------------------------------------------------------------
525
+ /**
526
+ * Create a 3DS session on the TagadaPay backend.
527
+ * This persists the session so the processor can use it during payment.
528
+ */
529
+ async create3dsSession(opts) {
530
+ return this.http.post("/api/public/v1/threeds/create-session", {
531
+ provider: opts.provider ?? "basis_theory",
532
+ storeId: this.storeId,
533
+ paymentInstrumentId: opts.paymentInstrumentId,
534
+ sessionData: opts.sessionData
535
+ });
536
+ }
537
+ // ---------------------------------------------------------------------------
538
+ // Payment processing
539
+ // ---------------------------------------------------------------------------
540
+ /**
541
+ * High-level pay: single API call that decodes tagadaToken server-side,
542
+ * creates the payment instrument, and processes payment.
543
+ *
544
+ * Also accepts `paymentInstrumentId` directly for pre-created instruments.
545
+ */
546
+ async pay(opts) {
547
+ if (opts.tagadaToken && !opts.paymentInstrumentId) {
548
+ return this.http.post("/api/v1/payment/pay-with-token", {
549
+ tagadaToken: opts.tagadaToken,
550
+ checkoutSessionId: opts.checkoutSessionId,
551
+ paymentFlowId: opts.paymentFlowId,
552
+ processorId: opts.processorId,
553
+ paymentMethod: opts.paymentMethod,
554
+ isExpress: opts.isExpress,
555
+ metadata: opts.metadata
556
+ });
557
+ }
558
+ return this.http.post("/api/public/v1/checkout/pay-v2", {
559
+ checkoutSessionId: opts.checkoutSessionId,
560
+ paymentInstrumentId: opts.paymentInstrumentId,
561
+ storeId: this.storeId,
562
+ paymentFlowId: opts.paymentFlowId,
563
+ threedsSessionId: opts.threedsSessionId,
564
+ processorId: opts.processorId,
565
+ paymentMethod: opts.paymentMethod,
566
+ isExpress: opts.isExpress,
567
+ metadata: opts.metadata
568
+ });
569
+ }
570
+ /**
571
+ * Low-level pay: process payment with an existing instrument or for APM/express flows
572
+ * where no instrument is needed (redirect-based methods).
573
+ */
574
+ async payDirect(opts) {
575
+ return this.http.post("/api/public/v1/checkout/pay-v2", {
576
+ checkoutSessionId: opts.checkoutSessionId,
577
+ paymentInstrumentId: opts.paymentInstrumentId ?? "",
578
+ storeId: this.storeId,
579
+ paymentFlowId: opts.paymentFlowId,
580
+ processorId: opts.processorId,
581
+ paymentMethod: opts.paymentMethod,
582
+ isExpress: opts.isExpress,
583
+ threedsSessionId: opts.threedsSessionId
584
+ });
585
+ }
586
+ /**
587
+ * Process an Apple Pay payment.
588
+ * Tokenizes the Apple Pay token and processes payment in one call.
589
+ */
590
+ async processApplePay(opts) {
591
+ const coreJs = await this.loadCoreJs();
592
+ const tokenizer = new coreJs.Tokenizer({ environment: this.environment });
593
+ await tokenizer.initialize();
594
+ const { tagadaToken } = await tokenizer.tokenizeApplePay(opts.applePayToken);
595
+ return this.pay({
596
+ checkoutSessionId: opts.checkoutSessionId,
597
+ tagadaToken,
598
+ paymentFlowId: opts.paymentFlowId,
599
+ processorId: opts.processorId,
600
+ paymentMethod: "apple_pay",
601
+ isExpress: true
602
+ });
603
+ }
604
+ /**
605
+ * Process a Google Pay payment.
606
+ * Tokenizes the Google Pay token and processes payment in one call.
607
+ */
608
+ async processGooglePay(opts) {
609
+ const coreJs = await this.loadCoreJs();
610
+ const tokenizer = new coreJs.Tokenizer({ environment: this.environment });
611
+ await tokenizer.initialize();
612
+ const { tagadaToken } = await tokenizer.tokenizeGooglePay(opts.googlePayToken);
613
+ return this.pay({
614
+ checkoutSessionId: opts.checkoutSessionId,
615
+ tagadaToken,
616
+ paymentFlowId: opts.paymentFlowId,
617
+ processorId: opts.processorId,
618
+ paymentMethod: "google_pay",
619
+ isExpress: true
620
+ });
621
+ }
622
+ /**
623
+ * Process an APM payment (Klarna, iDEAL, etc.) via redirect.
624
+ * These typically don't require a payment instrument -- the processor handles the redirect.
625
+ */
626
+ async processApm(opts) {
627
+ return this.payDirect({
628
+ checkoutSessionId: opts.checkoutSessionId,
629
+ paymentMethod: opts.paymentMethod,
630
+ processorId: opts.processorId,
631
+ paymentFlowId: opts.paymentFlowId
632
+ });
633
+ }
634
+ // ---------------------------------------------------------------------------
635
+ // Status polling
636
+ // ---------------------------------------------------------------------------
637
+ /** Get current status of a payment. */
638
+ async getPaymentStatus(paymentId) {
639
+ return this.http.get(`/api/v1/payments/${paymentId}`);
640
+ }
641
+ /**
642
+ * Poll a payment until it reaches a terminal status.
643
+ * Returns the final status or throws on timeout.
644
+ */
645
+ async pollPaymentStatus(paymentId, opts) {
646
+ const interval = (opts == null ? void 0 : opts.intervalMs) ?? 1500;
647
+ const timeout = (opts == null ? void 0 : opts.timeoutMs) ?? 6e4;
648
+ const start = Date.now();
649
+ while (Date.now() - start < timeout) {
650
+ const status = await this.getPaymentStatus(paymentId);
651
+ if (status.status === "succeeded" || status.status === "failed" || status.status === "declined") {
652
+ return status;
653
+ }
654
+ await new Promise((r) => setTimeout(r, interval));
655
+ }
656
+ throw new Error(`Payment ${paymentId} did not reach terminal status within ${timeout}ms.`);
657
+ }
658
+ /** Finalize a payment after a 3DS challenge completes. */
659
+ async completeAfter3ds(paymentId) {
660
+ return this.http.post("/api/v1/payments/complete-after-3ds", {
661
+ paymentId
662
+ });
663
+ }
664
+ // ---------------------------------------------------------------------------
665
+ // Internal helpers
666
+ // ---------------------------------------------------------------------------
667
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
668
+ async loadCoreJs() {
669
+ try {
670
+ return await import("@tagadapay/core-js");
671
+ } catch {
672
+ throw new Error(
673
+ "This method requires @tagadapay/core-js. Install it: npm install @tagadapay/core-js"
674
+ );
675
+ }
676
+ }
677
+ };
678
+
679
+ // src/core/modules/analytics.ts
680
+ var AnalyticsModule = class {
681
+ constructor(http, storeId) {
682
+ this.http = http;
683
+ this.storeId = storeId;
684
+ this.pixels = { loaded: false };
685
+ this.eventQueue = [];
686
+ this.dedupeSet = /* @__PURE__ */ new Set();
687
+ }
688
+ /**
689
+ * Initialize analytics by loading pixel configuration from the store.
690
+ * Call this once on page load. Events fired before init completes are queued.
691
+ */
692
+ async init(opts) {
693
+ if (this.pixels.loaded)
694
+ return;
695
+ let config = opts == null ? void 0 : opts.pixelConfig;
696
+ if (!config) {
697
+ try {
698
+ const res = await this.http.get(
699
+ "/api/v1/checkout/config",
700
+ { params: { storeId: this.storeId } }
701
+ );
702
+ config = res.pixels;
703
+ } catch {
704
+ }
705
+ }
706
+ this.pixels = { loaded: true, config };
707
+ if (typeof window !== "undefined" && config) {
708
+ this.loadPixelScripts(config);
709
+ }
710
+ this.flushQueue();
711
+ }
712
+ // ---------------------------------------------------------------------------
713
+ // Standard e-commerce events
714
+ // ---------------------------------------------------------------------------
715
+ trackPageView(page) {
716
+ this.fireEvent("PageView", { page: page ?? this.getCurrentPath() });
717
+ }
718
+ trackViewContent(data) {
719
+ this.fireEvent("ViewContent", data);
720
+ }
721
+ trackAddToCart(data) {
722
+ this.fireEvent("AddToCart", data);
723
+ }
724
+ trackInitiateCheckout(data) {
725
+ this.fireEvent("InitiateCheckout", data ?? {});
726
+ }
727
+ trackAddPaymentInfo(data) {
728
+ this.fireEvent("AddPaymentInfo", data ?? {});
729
+ }
730
+ trackPurchase(data) {
731
+ this.fireEvent("Purchase", data, true);
732
+ }
733
+ trackCustomEvent(event, data) {
734
+ this.fireEvent(event, data ?? {});
735
+ }
736
+ /** Track a funnel step (maps to Tagada's funnel tracking endpoint). */
737
+ trackStep(data) {
738
+ this.fireEvent("FunnelStep", data);
739
+ this.http.post("/api/v1/funnel-tracking/step", {
740
+ storeId: this.storeId,
741
+ ...data
742
+ }).catch(() => {
743
+ });
744
+ }
745
+ trackConversion(data) {
746
+ this.fireEvent("Conversion", data, true);
747
+ }
748
+ // ---------------------------------------------------------------------------
749
+ // Internals
750
+ // ---------------------------------------------------------------------------
751
+ fireEvent(event, data, dedupe = false) {
752
+ if (dedupe) {
753
+ const key = `${event}:${JSON.stringify(data)}`;
754
+ if (this.dedupeSet.has(key))
755
+ return;
756
+ this.dedupeSet.add(key);
757
+ }
758
+ if (!this.pixels.loaded) {
759
+ this.eventQueue.push({ event, data });
760
+ return;
761
+ }
762
+ this.sendToMeta(event, data);
763
+ this.sendToTikTok(event, data);
764
+ this.sendToSnapchat(event, data);
765
+ this.sendToGTM(event, data);
766
+ this.sendToGA(event, data);
767
+ }
768
+ flushQueue() {
769
+ const queue = [...this.eventQueue];
770
+ this.eventQueue = [];
771
+ for (const { event, data } of queue) {
772
+ this.fireEvent(event, data);
773
+ }
774
+ }
775
+ getCurrentPath() {
776
+ return typeof window !== "undefined" ? window.location.pathname : "/";
777
+ }
778
+ // ---------------------------------------------------------------------------
779
+ // Pixel script loaders
780
+ // ---------------------------------------------------------------------------
781
+ loadPixelScripts(config) {
782
+ if (config.metaPixelId)
783
+ this.loadMetaPixel(config.metaPixelId);
784
+ if (config.tiktokPixelId)
785
+ this.loadTikTokPixel(config.tiktokPixelId);
786
+ if (config.snapchatPixelId)
787
+ this.loadSnapchatPixel(config.snapchatPixelId);
788
+ if (config.gtmId)
789
+ this.loadGTM(config.gtmId);
790
+ if (config.gaId)
791
+ this.loadGA(config.gaId);
792
+ }
793
+ loadMetaPixel(pixelId) {
794
+ if (typeof window === "undefined")
795
+ return;
796
+ const w = window;
797
+ if (w.fbq)
798
+ return;
799
+ const n = w.fbq = function(...args) {
800
+ n.callMethod ? n.callMethod(...args) : n.queue.push(args);
801
+ };
802
+ n.queue = [];
803
+ n.loaded = true;
804
+ n.version = "2.0";
805
+ this.injectScript("https://connect.facebook.net/en_US/fbevents.js");
806
+ w.fbq("init", pixelId);
807
+ }
808
+ loadTikTokPixel(pixelId) {
809
+ if (typeof window === "undefined")
810
+ return;
811
+ const w = window;
812
+ if (w.ttq)
813
+ return;
814
+ const ttq = {};
815
+ ttq.methods = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie"];
816
+ ttq.setAndDefer = function(t, e) {
817
+ t[e] = function(...args) {
818
+ t.push([e, ...args]);
819
+ };
820
+ };
821
+ w.ttq = ttq;
822
+ this.injectScript("https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=" + pixelId);
823
+ }
824
+ loadSnapchatPixel(pixelId) {
825
+ if (typeof window === "undefined")
826
+ return;
827
+ const w = window;
828
+ if (w.snaptr)
829
+ return;
830
+ w.snaptr = function(...args) {
831
+ w.snaptr.handleRequest ? w.snaptr.handleRequest(...args) : w.snaptr.queue.push(args);
832
+ };
833
+ w.snaptr.queue = [];
834
+ this.injectScript("https://sc-static.net/scevent.min.js");
835
+ w.snaptr("init", pixelId);
836
+ }
837
+ loadGTM(gtmId) {
838
+ if (typeof window === "undefined")
839
+ return;
840
+ const w = window;
841
+ w.dataLayer = w.dataLayer ?? [];
842
+ w.dataLayer.push({ "gtm.start": Date.now(), event: "gtm.js" });
843
+ this.injectScript(`https://www.googletagmanager.com/gtm.js?id=${gtmId}`);
844
+ }
845
+ loadGA(gaId) {
846
+ if (typeof window === "undefined")
847
+ return;
848
+ this.injectScript(`https://www.googletagmanager.com/gtag/js?id=${gaId}`);
849
+ const w = window;
850
+ w.dataLayer = w.dataLayer ?? [];
851
+ w.gtag = function(...args) {
852
+ w.dataLayer.push(args);
853
+ };
854
+ w.gtag("js", /* @__PURE__ */ new Date());
855
+ w.gtag("config", gaId);
856
+ }
857
+ injectScript(src) {
858
+ if (typeof document === "undefined")
859
+ return;
860
+ const s = document.createElement("script");
861
+ s.async = true;
862
+ s.src = src;
863
+ document.head.appendChild(s);
864
+ }
865
+ // ---------------------------------------------------------------------------
866
+ // Event dispatchers per pixel
867
+ // ---------------------------------------------------------------------------
868
+ sendToMeta(event, data) {
869
+ const w = typeof window !== "undefined" ? window : null;
870
+ const fbq = w == null ? void 0 : w.fbq;
871
+ if (!fbq)
872
+ return;
873
+ const metaEventMap = {
874
+ PageView: "PageView",
875
+ ViewContent: "ViewContent",
876
+ AddToCart: "AddToCart",
877
+ InitiateCheckout: "InitiateCheckout",
878
+ AddPaymentInfo: "AddPaymentInfo",
879
+ Purchase: "Purchase"
880
+ };
881
+ const mapped = metaEventMap[event];
882
+ if (mapped) {
883
+ fbq("track", mapped, data);
884
+ } else {
885
+ fbq("trackCustom", event, data);
886
+ }
887
+ }
888
+ sendToTikTok(event, data) {
889
+ var _a, _b;
890
+ const w = typeof window !== "undefined" ? window : null;
891
+ const ttq = w == null ? void 0 : w.ttq;
892
+ if (!ttq)
893
+ return;
894
+ if (event === "PageView") {
895
+ (_a = ttq.page) == null ? void 0 : _a.call(ttq);
896
+ } else {
897
+ (_b = ttq.track) == null ? void 0 : _b.call(ttq, event, data);
898
+ }
899
+ }
900
+ sendToSnapchat(event, data) {
901
+ const w = typeof window !== "undefined" ? window : null;
902
+ const snaptr = w == null ? void 0 : w.snaptr;
903
+ if (!snaptr)
904
+ return;
905
+ const snapEventMap = {
906
+ PageView: "PAGE_VIEW",
907
+ ViewContent: "VIEW_CONTENT",
908
+ AddToCart: "ADD_CART",
909
+ InitiateCheckout: "START_CHECKOUT",
910
+ Purchase: "PURCHASE"
911
+ };
912
+ const mapped = snapEventMap[event];
913
+ if (mapped)
914
+ snaptr("track", mapped, data);
915
+ }
916
+ sendToGTM(event, data) {
917
+ const w = typeof window !== "undefined" ? window : null;
918
+ const dataLayer = w == null ? void 0 : w.dataLayer;
919
+ if (!dataLayer)
920
+ return;
921
+ dataLayer.push({ event, ...data });
922
+ }
923
+ sendToGA(event, data) {
924
+ const w = typeof window !== "undefined" ? window : null;
925
+ const gtag = w == null ? void 0 : w.gtag;
926
+ if (!gtag)
927
+ return;
928
+ gtag("event", event, data);
929
+ }
930
+ };
931
+
932
+ // src/core/modules/offers.ts
933
+ var OffersModule = class {
934
+ constructor(http, storeId) {
935
+ this.http = http;
936
+ this.storeId = storeId;
937
+ }
938
+ /** Load offer details by ID. */
939
+ async loadOffer(offerId) {
940
+ const res = await this.http.get(
941
+ `/api/v1/checkout-offers/${offerId}`,
942
+ { params: { storeId: this.storeId } }
943
+ );
944
+ return res.offer;
945
+ }
946
+ /** List all offers for the store. */
947
+ async listOffers(opts) {
948
+ const res = await this.http.get(
949
+ "/api/v1/checkout-offers",
950
+ { params: { storeId: this.storeId, type: opts == null ? void 0 : opts.type } }
951
+ );
952
+ return res.offers;
953
+ }
954
+ /**
955
+ * Accept an offer (one-click upsell).
956
+ * Charges the stored payment instrument from the main checkout order.
957
+ */
958
+ async acceptOffer(opts) {
959
+ return this.http.post("/api/v1/checkout-offers/accept", {
960
+ offerId: opts.offerId,
961
+ checkoutSessionId: opts.checkoutSessionId,
962
+ storeId: this.storeId,
963
+ paymentInstrumentId: opts.paymentInstrumentId
964
+ });
965
+ }
966
+ /** Decline an offer. Advances the funnel to the next step. */
967
+ async declineOffer(opts) {
968
+ return this.http.post("/api/v1/checkout-offers/decline", {
969
+ offerId: opts.offerId,
970
+ checkoutSessionId: opts.checkoutSessionId,
971
+ storeId: this.storeId
972
+ });
973
+ }
974
+ /** List order bumps available for a checkout session (shown on the checkout page). */
975
+ async listOrderBumps(checkoutSessionId) {
976
+ const res = await this.http.get(
977
+ "/api/v1/checkout-offers",
978
+ { params: { storeId: this.storeId, checkoutSessionId, type: "orderbump" } }
979
+ );
980
+ return res.offers;
981
+ }
982
+ /** Toggle an order bump on/off for a checkout session. */
983
+ async toggleOrderBump(opts) {
984
+ await this.http.post(`/api/v1/checkout-sessions/${opts.checkoutSessionId}/order-bumps`, {
985
+ offerId: opts.offerId,
986
+ selected: opts.selected
987
+ });
988
+ }
989
+ };
990
+
991
+ // src/core/modules/customer.ts
992
+ var CustomerModule = class {
993
+ constructor(http, storeId) {
994
+ this.http = http;
995
+ this.storeId = storeId;
996
+ }
997
+ /** Get customer profile by ID. */
998
+ async getProfile(customerId) {
999
+ const res = await this.http.get(
1000
+ `/api/v1/customers/${customerId}`,
1001
+ { params: { storeId: this.storeId } }
1002
+ );
1003
+ return res.customer;
1004
+ }
1005
+ /** Get customer profile by email. */
1006
+ async getByEmail(email) {
1007
+ try {
1008
+ const res = await this.http.get(
1009
+ "/api/v1/customers/by-email",
1010
+ { params: { email, storeId: this.storeId } }
1011
+ );
1012
+ return res.customer;
1013
+ } catch {
1014
+ return null;
1015
+ }
1016
+ }
1017
+ /** Update customer profile fields. */
1018
+ async updateProfile(customerId, data) {
1019
+ const res = await this.http.patch(
1020
+ `/api/v1/customers/${customerId}`,
1021
+ { storeId: this.storeId, ...data }
1022
+ );
1023
+ return res.customer;
1024
+ }
1025
+ /** List orders for a customer. */
1026
+ async getOrders(customerId, opts) {
1027
+ return this.http.get(
1028
+ `/api/v1/customers/${customerId}/orders`,
1029
+ { params: { storeId: this.storeId, limit: opts == null ? void 0 : opts.limit, offset: opts == null ? void 0 : opts.offset } }
1030
+ );
1031
+ }
1032
+ /** Get a single order by ID. */
1033
+ async getOrder(orderId) {
1034
+ const res = await this.http.get(`/api/v1/orders/${orderId}`, {
1035
+ params: { storeId: this.storeId }
1036
+ });
1037
+ return res.order;
1038
+ }
1039
+ /** List subscriptions for a customer. */
1040
+ async getSubscriptions(customerId) {
1041
+ const res = await this.http.get(
1042
+ `/api/v1/customers/${customerId}/subscriptions`,
1043
+ { params: { storeId: this.storeId } }
1044
+ );
1045
+ return res.subscriptions;
1046
+ }
1047
+ /** Get a single subscription by ID. */
1048
+ async getSubscription(subscriptionId) {
1049
+ const res = await this.http.get(
1050
+ `/api/v1/subscriptions/${subscriptionId}`,
1051
+ { params: { storeId: this.storeId } }
1052
+ );
1053
+ return res.subscription;
1054
+ }
1055
+ };
1056
+
1057
+ // src/core/client.ts
1058
+ var HeadlessClient = class {
1059
+ constructor(config) {
1060
+ const environment = config.environment ?? "production";
1061
+ const baseUrl = HttpClient.resolveBaseUrl(environment, config.baseUrl);
1062
+ this.config = {
1063
+ ...config,
1064
+ environment,
1065
+ baseUrl,
1066
+ timeout: config.timeout ?? 3e4
1067
+ };
1068
+ this.http = new HttpClient({
1069
+ baseUrl,
1070
+ timeout: this.config.timeout,
1071
+ apiKey: config.apiKey,
1072
+ getToken: () => this._sessionToken
1073
+ });
1074
+ const setToken = (token) => {
1075
+ this._sessionToken = token;
1076
+ };
1077
+ this.checkout = new CheckoutModule(this.http, this.config.storeId, setToken);
1078
+ this.payment = new PaymentModule(this.http, this.config.storeId, environment);
1079
+ this.analytics = new AnalyticsModule(this.http, this.config.storeId);
1080
+ this.offers = new OffersModule(this.http, this.config.storeId);
1081
+ this.customer = new CustomerModule(this.http, this.config.storeId);
1082
+ }
1083
+ /** Manually set the session token (e.g. from URL params on page load). */
1084
+ setSessionToken(token) {
1085
+ this._sessionToken = token;
1086
+ }
1087
+ };
1088
+ function createHeadlessClient(config) {
1089
+ return new HeadlessClient(config);
1090
+ }
1091
+ return __toCommonJS(core_exports);
1092
+ })();
1093
+ if(typeof window!=="undefined"&&TagadaHeadlessBundle){ window.TagadaHeadless=TagadaHeadlessBundle; window.TagadaHeadless.create=TagadaHeadlessBundle.createHeadlessClient;}