@monei-js/components 1.7.9 → 2.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 (56) hide show
  1. package/README.md +72 -9
  2. package/dist/chunk.js +13 -0
  3. package/dist/index.cjs +1623 -0
  4. package/dist/index.d.cts +510 -0
  5. package/dist/index.d.ts +508 -14
  6. package/dist/index.js +1596 -7
  7. package/dist/monei.umd.production.min.js +64 -0
  8. package/dist/monei.umd.production.min.js.map +1 -0
  9. package/package.json +41 -65
  10. package/src/bridge/types.ts +102 -0
  11. package/dist/api.d.ts +0 -13
  12. package/dist/bizum/container.d.ts +0 -4
  13. package/dist/bizum/index.d.ts +0 -5
  14. package/dist/bizum/modal.d.ts +0 -3
  15. package/dist/bizum/types.d.ts +0 -30
  16. package/dist/cardInput/index.d.ts +0 -8
  17. package/dist/cardInput/types.d.ts +0 -51
  18. package/dist/click2pay/container.d.ts +0 -4
  19. package/dist/click2pay/index.d.ts +0 -5
  20. package/dist/click2pay/modal.d.ts +0 -3
  21. package/dist/click2pay/types.d.ts +0 -23
  22. package/dist/cofidis/container.d.ts +0 -4
  23. package/dist/cofidis/index.d.ts +0 -6
  24. package/dist/cofidis/modal.d.ts +0 -3
  25. package/dist/cofidis/types.d.ts +0 -45
  26. package/dist/cofidis/widget.d.ts +0 -3
  27. package/dist/cofidisLoan/container.d.ts +0 -4
  28. package/dist/cofidisLoan/index.d.ts +0 -7
  29. package/dist/cofidisLoan/modal.d.ts +0 -4
  30. package/dist/cofidisLoan/types.d.ts +0 -45
  31. package/dist/cofidisLoan/widget.d.ts +0 -4
  32. package/dist/components.cjs.development.js +0 -18927
  33. package/dist/components.cjs.development.js.map +0 -1
  34. package/dist/components.cjs.production.min.js +0 -2
  35. package/dist/components.cjs.production.min.js.map +0 -1
  36. package/dist/components.esm.js +0 -18909
  37. package/dist/components.esm.js.map +0 -1
  38. package/dist/config.d.ts +0 -28
  39. package/dist/container.d.ts +0 -1
  40. package/dist/enums.d.ts +0 -4
  41. package/dist/googlePay/index.d.ts +0 -4
  42. package/dist/googlePay/types.d.ts +0 -21
  43. package/dist/paymentModal/container.d.ts +0 -4
  44. package/dist/paymentModal/index.d.ts +0 -6
  45. package/dist/paymentModal/types.d.ts +0 -28
  46. package/dist/paymentRequest/index.d.ts +0 -4
  47. package/dist/paymentRequest/types.d.ts +0 -22
  48. package/dist/paypal/index.d.ts +0 -4
  49. package/dist/paypal/types.d.ts +0 -27
  50. package/dist/types.d.ts +0 -194
  51. package/dist/utils.d.ts +0 -11
  52. package/types/belter.d.ts +0 -1
  53. package/types/component.d.ts +0 -196
  54. package/types/css.d.ts +0 -9
  55. package/types/global.d.ts +0 -3
  56. package/types/post-robot.d.ts +0 -1
package/dist/index.js CHANGED
@@ -1,8 +1,1597 @@
1
-
2
- 'use strict'
3
-
4
- if (process.env.NODE_ENV === 'production') {
5
- module.exports = require('./components.cjs.production.min.js')
6
- } else {
7
- module.exports = require('./components.cjs.development.js')
1
+ import { t as __exportAll } from "./chunk.js";
2
+ import { Thumbmark } from "@thumbmarkjs/thumbmarkjs";
3
+ import { WindowMessenger, connect } from "penpal";
4
+ //#region ../shared/lib/utils.ts
5
+ /** Parse a CSS px value — accepts "10px", "10", or 10. Returns number or defaultValue. */
6
+ const parsePx = (value, defaultValue) => {
7
+ if (value == null) return defaultValue;
8
+ if (typeof value === "number") return value;
9
+ const parsed = parseInt(value);
10
+ return isNaN(parsed) ? defaultValue : parsed;
11
+ };
12
+ /** Convert a value to CSS px string — 10 → "10px", "10px" → "10px", undefined → defaultValue */
13
+ const toCssPx = (value, defaultValue) => {
14
+ if (value == null) return defaultValue;
15
+ return typeof value === "number" ? `${value}px` : value || defaultValue;
16
+ };
17
+ //#endregion
18
+ //#region src/utils.ts
19
+ var utils_exports = /* @__PURE__ */ __exportAll({
20
+ fixLocalstorage: () => fixLocalstorage,
21
+ getClientEnv: () => getClientEnv,
22
+ getClientFingerprint: () => getClientFingerprint,
23
+ isMethodSupported: () => isMethodSupported,
24
+ loadScript: () => loadScript,
25
+ parsePx: () => parsePx,
26
+ stringify: () => stringify,
27
+ toCssPx: () => toCssPx,
28
+ transformStyle: () => transformStyle,
29
+ validateComponentProps: () => validateComponentProps,
30
+ withError: () => withError
31
+ });
32
+ const transformStyle = (style) => {
33
+ return Object.keys(style).reduce((result, prop) => {
34
+ if (typeof style[prop] === "string") result[prop] = style[prop];
35
+ else result[prop] = `${style[prop]}px`;
36
+ return result;
37
+ }, {});
38
+ };
39
+ const loadScript = (src, nonce, dataset, forceReload) => {
40
+ return new Promise((resolve, reject) => {
41
+ const existingScript = Array.from(document.scripts).find((s) => s.src === src);
42
+ if (existingScript) if (forceReload) existingScript.remove();
43
+ else {
44
+ resolve(existingScript);
45
+ return;
46
+ }
47
+ const script = document.createElement("script");
48
+ script.src = src;
49
+ script.onload = () => resolve(script);
50
+ script.onerror = (error) => reject(error);
51
+ if (nonce) script.setAttribute("nonce", nonce);
52
+ if (dataset) Object.keys(dataset).forEach((key) => {
53
+ if (dataset[key]) script.dataset[key] = dataset[key];
54
+ });
55
+ document.head.appendChild(script);
56
+ });
57
+ };
58
+ const stringify = (obj) => {
59
+ return Object.keys(obj).reduce((result, key) => {
60
+ if (obj[key] !== void 0) result.push(`${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`);
61
+ return result;
62
+ }, []).join("&");
63
+ };
64
+ const fixLocalstorage = () => {
65
+ let localStorage;
66
+ try {
67
+ ({localStorage} = window);
68
+ } catch (_error) {
69
+ const localStorageMock = (() => {
70
+ let store = /* @__PURE__ */ new Map();
71
+ return {
72
+ getItem(key) {
73
+ return store.get(key);
74
+ },
75
+ setItem: function(key, value) {
76
+ store.set(key, value);
77
+ },
78
+ clear: function() {
79
+ store = /* @__PURE__ */ new Map();
80
+ },
81
+ removeItem: function(key) {
82
+ store.delete(key);
83
+ }
84
+ };
85
+ })();
86
+ Object.defineProperty(window, "localStorage", { value: localStorageMock });
87
+ localStorage = localStorageMock;
88
+ }
89
+ return localStorage;
90
+ };
91
+ const getLanguage = () => {
92
+ let lang;
93
+ const localStorage = fixLocalstorage();
94
+ try {
95
+ lang = localStorage.getItem("i18nextLng");
96
+ } catch (_error) {}
97
+ if (lang) return lang.split("-")[0];
98
+ return "";
99
+ };
100
+ const safe = (fn) => {
101
+ try {
102
+ return String(fn() ?? "");
103
+ } catch {
104
+ return "";
105
+ }
106
+ };
107
+ const getClientEnv = () => {
108
+ const env = [
109
+ window.screen.colorDepth,
110
+ window.screen.height,
111
+ window.screen.width,
112
+ (/* @__PURE__ */ new Date()).getTimezoneOffset(),
113
+ getLanguage(),
114
+ safe(() => Intl.DateTimeFormat().resolvedOptions().timeZone),
115
+ safe(() => window.devicePixelRatio),
116
+ safe(() => navigator.hardwareConcurrency),
117
+ safe(() => navigator.deviceMemory),
118
+ safe(() => navigator.maxTouchPoints),
119
+ safe(() => navigator.platform),
120
+ safe(() => navigator.languages?.join(","))
121
+ ].join("|");
122
+ return window.btoa(env);
123
+ };
124
+ const FINGERPRINT_SEED_KEY = "_monei_fp";
125
+ const randomHex = (length) => {
126
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
127
+ const bytes = new Uint8Array(length);
128
+ crypto.getRandomValues(bytes);
129
+ return Array.from(bytes, (b) => (b % 16).toString(16)).join("");
130
+ }
131
+ return Array.from({ length }, () => Math.floor(Math.random() * 16).toString(16)).join("");
132
+ };
133
+ let cachedSeed = null;
134
+ const getPersistentSeed = async () => {
135
+ if (cachedSeed) return { seed: cachedSeed };
136
+ try {
137
+ const localStorage = fixLocalstorage();
138
+ cachedSeed = localStorage.getItem(FINGERPRINT_SEED_KEY);
139
+ if (!cachedSeed) {
140
+ cachedSeed = randomHex(32);
141
+ try {
142
+ localStorage.setItem(FINGERPRINT_SEED_KEY, cachedSeed);
143
+ } catch {}
144
+ }
145
+ } catch {
146
+ cachedSeed = randomHex(32);
147
+ }
148
+ return { seed: cachedSeed };
149
+ };
150
+ const thumbmark = new Thumbmark({ logging: false });
151
+ thumbmark.includeComponent("persistent_seed", getPersistentSeed);
152
+ const getClientFingerprint = async () => {
153
+ const [, result] = await withError(thumbmark.get());
154
+ return result?.thumbmark ?? "";
155
+ };
156
+ const withError = async (p) => {
157
+ try {
158
+ return [void 0, await p];
159
+ } catch (err) {
160
+ return [err, void 0];
161
+ }
162
+ };
163
+ const isMethodSupported = (config, paymentMethod) => {
164
+ return config.paymentMethods && config.paymentMethods.includes(paymentMethod);
165
+ };
166
+ const validateComponentProps = ({ props }) => {
167
+ if (props.paymentId) return;
168
+ if (props.accountId && props.amount && props.currency) return;
169
+ throw new Error("You need to provide paymentId or accountId amount and currency");
170
+ };
171
+ //#endregion
172
+ //#region src/config.ts
173
+ const stage = import.meta.env?.STAGE || "local";
174
+ const domain = import.meta.env?.DOMAIN || "http://localhost:3001";
175
+ const version = import.meta.env?.VERSION || "v1";
176
+ const globalConfig = {
177
+ domain,
178
+ version,
179
+ stage,
180
+ isProduction: stage === "prod",
181
+ paymentPageUrl: `${domain}/${version}/payment-page/`,
182
+ cardInputUrl: `${domain}/${version}/inner-card-input/`,
183
+ paymentModalUrl: `${domain}/${version}/inner-payment-modal/`,
184
+ paypalUrl: `${domain}/${version}/inner-paypal/`,
185
+ bizumUrl: `${domain}/${version}/inner-bizum/`,
186
+ bizumButtonUrl: `${domain}/${version}/inner-bizum-button/`,
187
+ paymentRequestUrl: `${domain}/${version}/inner-payment-request/`
188
+ };
189
+ const stageConfig = {
190
+ local: {
191
+ domain: "http://card-input.localhost:1355",
192
+ paymentPageUrl: `http://payment-page.localhost:1355/`,
193
+ cardInputUrl: `http://card-input.localhost:1355/`,
194
+ paymentModalUrl: `http://payment-modal.localhost:1355/`,
195
+ paypalUrl: `http://paypal.localhost:1355/`,
196
+ bizumUrl: `http://bizum.localhost:1355/`,
197
+ bizumButtonUrl: `http://bizum-button.localhost:1355/`,
198
+ paymentRequestUrl: `http://payment-request.localhost:1355/`,
199
+ apiUrl: "https://api.monei-dev.com/v1",
200
+ secureDomain: "https://secure.monei-dev.com",
201
+ rootDomain: "monei-dev.com"
202
+ },
203
+ "local-prod": {
204
+ domain: "http://card-input.localhost:1355",
205
+ paymentPageUrl: `http://payment-page.localhost:1355/`,
206
+ cardInputUrl: `http://card-input.localhost:1355/`,
207
+ paymentModalUrl: `http://payment-modal.localhost:1355/`,
208
+ paypalUrl: `http://paypal.localhost:1355/`,
209
+ bizumUrl: `http://bizum.localhost:1355/`,
210
+ bizumButtonUrl: `http://bizum-button.localhost:1355/`,
211
+ paymentRequestUrl: `http://payment-request.localhost:1355/`,
212
+ apiUrl: "https://api.monei.com/v1",
213
+ secureDomain: "https://secure.monei.com",
214
+ rootDomain: "monei.com"
215
+ },
216
+ tunnel: {
217
+ domain: "https://card-input.monei-dev-tunnel.com",
218
+ paymentPageUrl: `https://payment-page.monei-dev-tunnel.com/`,
219
+ cardInputUrl: `https://card-input.monei-dev-tunnel.com/`,
220
+ paymentModalUrl: `https://payment-modal.monei-dev-tunnel.com/`,
221
+ paypalUrl: `https://paypal.monei-dev-tunnel.com/`,
222
+ bizumUrl: `https://bizum.monei-dev-tunnel.com/`,
223
+ bizumButtonUrl: `https://bizum-button.monei-dev-tunnel.com/`,
224
+ paymentRequestUrl: `https://payment-request.monei-dev-tunnel.com/`,
225
+ apiUrl: "https://api.monei.com/v1",
226
+ secureDomain: "https://secure.monei.com",
227
+ rootDomain: "monei.com"
228
+ },
229
+ dev: {
230
+ apiUrl: "https://api.monei-dev.com/v1",
231
+ secureDomain: "https://secure.monei-dev.com",
232
+ rootDomain: "monei-dev.com"
233
+ },
234
+ prod: {
235
+ apiUrl: "https://api.monei.com/v1",
236
+ secureDomain: "https://secure.monei.com",
237
+ rootDomain: "monei.com"
238
+ }
239
+ };
240
+ const config = {
241
+ ...globalConfig,
242
+ ...stageConfig[stage]
243
+ };
244
+ //#endregion
245
+ //#region src/api.ts
246
+ var api_exports = /* @__PURE__ */ __exportAll({
247
+ confirmPayment: () => confirmPayment$1,
248
+ createApplePaySession: () => createApplePaySession,
249
+ createPayment: () => createPayment,
250
+ createToken: () => createToken$1,
251
+ getPayment: () => getPayment,
252
+ getPaymentMethods: () => getPaymentMethods,
253
+ sendPaymentReceipt: () => sendPaymentReceipt,
254
+ validateBizumPhone: () => validateBizumPhone
255
+ });
256
+ const request = async (url, { method = "GET", headers, body } = {}) => {
257
+ if (method === "POST") headers = {
258
+ "Content-Type": "application/json",
259
+ ...headers
260
+ };
261
+ const res = await fetch(`${config.apiUrl}${url}`, {
262
+ method,
263
+ headers,
264
+ body: body ? JSON.stringify(body) : void 0
265
+ });
266
+ const [, result] = await withError(res.json());
267
+ if (!res.ok) throw result || new Error(res.statusText);
268
+ return result;
269
+ };
270
+ const pmCache = {};
271
+ const getPaymentMethods = async ({ accountId, paymentId }) => {
272
+ let params;
273
+ if (paymentId) params = { paymentId };
274
+ else if (accountId) params = { accountId };
275
+ else throw new Error("You need to provide paymentId or accountId");
276
+ const query = stringify(params);
277
+ if (query in pmCache) return pmCache[query];
278
+ const promise = request(`/payment-methods?${query}`);
279
+ pmCache[query] = promise;
280
+ promise.catch(() => delete pmCache[query]);
281
+ return promise;
282
+ };
283
+ const createToken$1 = async ({ paymentMethod, paymentId, sessionId, amount, currency, accountId, transactionType }) => {
284
+ let body;
285
+ if (paymentId) body = {
286
+ paymentId,
287
+ paymentMethod
288
+ };
289
+ else if (accountId) body = {
290
+ accountId,
291
+ paymentMethod,
292
+ sessionId,
293
+ amount,
294
+ currency,
295
+ transactionType
296
+ };
297
+ else throw new Error("You need to provide paymentId or accountId");
298
+ const res = await request("/tokens", {
299
+ method: "POST",
300
+ headers: {
301
+ "X-Client-Env": getClientEnv(),
302
+ "X-Client-Fingerprint": await getClientFingerprint()
303
+ },
304
+ body
305
+ });
306
+ if (res.paymentToken && !res.token) res.token = res.paymentToken;
307
+ return res;
308
+ };
309
+ const getPayment = async (paymentId) => {
310
+ return request(`/payments/${paymentId}/client-get`);
311
+ };
312
+ const confirmPayment$1 = async ({ paymentId, ...body }) => {
313
+ return request(`/payments/${paymentId}/client-confirm`, {
314
+ method: "POST",
315
+ headers: {
316
+ "X-Client-Env": getClientEnv(),
317
+ "X-Client-Fingerprint": await getClientFingerprint()
318
+ },
319
+ body
320
+ });
321
+ };
322
+ const createPayment = async ({ signature, ...body }) => {
323
+ return request("/client-payments", {
324
+ method: "POST",
325
+ headers: {
326
+ "X-Client-Env": getClientEnv(),
327
+ "X-Client-Fingerprint": await getClientFingerprint(),
328
+ "Client-Signature": signature
329
+ },
330
+ body
331
+ });
332
+ };
333
+ const sendPaymentReceipt = async ({ paymentId, customerEmail, signature, language }) => {
334
+ return request(`/payments/${paymentId}/client-receipt`, {
335
+ method: "POST",
336
+ body: {
337
+ customerEmail,
338
+ signature,
339
+ language
340
+ }
341
+ });
342
+ };
343
+ const createApplePaySession = async (body) => {
344
+ return request(`/apple-pay/sessions`, {
345
+ method: "POST",
346
+ body
347
+ });
348
+ };
349
+ const validateBizumPhone = async (req) => {
350
+ return request(`/bizum/validate-phone`, {
351
+ method: "POST",
352
+ body: req
353
+ });
354
+ };
355
+ //#endregion
356
+ //#region src/bridge/event-emitter.ts
357
+ var EventEmitter = class {
358
+ constructor() {
359
+ this.listeners = /* @__PURE__ */ new Map();
360
+ this.destroyed = false;
361
+ }
362
+ on(eventName, handler) {
363
+ if (this.destroyed) return { cancel: () => {} };
364
+ let handlers = this.listeners.get(eventName);
365
+ if (!handlers) {
366
+ handlers = /* @__PURE__ */ new Set();
367
+ this.listeners.set(eventName, handlers);
368
+ }
369
+ handlers.add(handler);
370
+ return { cancel: () => {
371
+ handlers.delete(handler);
372
+ } };
373
+ }
374
+ once(eventName, handler) {
375
+ const wrapper = (...args) => {
376
+ this.off(eventName, wrapper);
377
+ handler(...args);
378
+ };
379
+ return this.on(eventName, wrapper);
380
+ }
381
+ trigger(eventName, ...args) {
382
+ if (this.destroyed) return;
383
+ const handlers = this.listeners.get(eventName);
384
+ if (!handlers) return;
385
+ for (const handler of handlers) try {
386
+ handler(...args);
387
+ } catch (e) {
388
+ console.error(e);
389
+ }
390
+ }
391
+ off(eventName, handler) {
392
+ const handlers = this.listeners.get(eventName);
393
+ if (handlers) handlers.delete(handler);
394
+ }
395
+ destroy() {
396
+ this.destroyed = true;
397
+ this.listeners.clear();
398
+ }
399
+ };
400
+ //#endregion
401
+ //#region src/bridge/drivers/react.ts
402
+ /**
403
+ * Creates a React driver for a bridge component.
404
+ * Returns a forwardRef component that:
405
+ * - On mount: creates bridge instance, renders into container div
406
+ * - On update: calls updateProps with new props
407
+ * - On unmount: calls destroy
408
+ * - Exposes bridge instance via ref (needed for CardInput's createToken)
409
+ */
410
+ function createReactDriver(ComponentClass) {
411
+ return ({ React }) => {
412
+ return React.forwardRef(function BridgeReactWrapper(props, ref) {
413
+ const containerRef = React.useRef(null);
414
+ const instanceRef = React.useRef(null);
415
+ const isMounted = React.useRef(false);
416
+ const prevPropsRef = React.useRef({});
417
+ React.useLayoutEffect(() => {
418
+ const el = containerRef.current;
419
+ if (!el) return;
420
+ let cancelled = false;
421
+ const instance = new ComponentClass({ ...props });
422
+ instanceRef.current = instance;
423
+ instance.render(el).then(() => {
424
+ if (cancelled) return;
425
+ setRef(ref, instance);
426
+ isMounted.current = true;
427
+ }).catch((err) => {
428
+ if (!cancelled) console.error(err);
429
+ });
430
+ return () => {
431
+ cancelled = true;
432
+ instance.destroy();
433
+ instanceRef.current = null;
434
+ isMounted.current = false;
435
+ setRef(ref, null);
436
+ };
437
+ }, []);
438
+ React.useEffect(() => {
439
+ if (!isMounted.current || !instanceRef.current) return;
440
+ if (shallowEqual$1(prevPropsRef.current, props)) return;
441
+ prevPropsRef.current = { ...props };
442
+ instanceRef.current.updateProps({ ...props }).catch(noop);
443
+ });
444
+ return React.createElement("div", { ref: containerRef });
445
+ });
446
+ };
8
447
  }
448
+ /** Set a React ref (callback or object ref) */
449
+ function setRef(ref, value) {
450
+ if (typeof ref === "function") ref(value);
451
+ else if (ref) ref.current = value;
452
+ }
453
+ function shallowEqual$1(a, b) {
454
+ const keysA = Object.keys(a);
455
+ const keysB = Object.keys(b);
456
+ if (keysA.length !== keysB.length) return false;
457
+ for (const key of keysA) if (a[key] !== b[key]) return false;
458
+ return true;
459
+ }
460
+ function noop() {}
461
+ //#endregion
462
+ //#region src/bridge/drivers/vue.ts
463
+ /**
464
+ * Creates a Vue 3 driver for a bridge component.
465
+ * Returns a Vue component options object that:
466
+ * - On mounted: creates bridge instance, renders into template div
467
+ * - On $attrs change: calls updateProps
468
+ * - On unmounted: calls destroy
469
+ * - Exposes bridge instance via template ref
470
+ */
471
+ function createVue3Driver(ComponentClass) {
472
+ return () => ({
473
+ template: "<div></div>",
474
+ inheritAttrs: false,
475
+ mounted() {
476
+ const el = this.$el;
477
+ this.__bridgeInstance = new ComponentClass({ ...this.$attrs });
478
+ this.__bridgeInstance.render(el).catch(console.error);
479
+ },
480
+ watch: { $attrs: {
481
+ handler() {
482
+ if (this.__bridgeInstance) this.__bridgeInstance.updateProps({ ...this.$attrs }).catch(() => {});
483
+ },
484
+ deep: true
485
+ } },
486
+ unmounted() {
487
+ if (this.__bridgeInstance) {
488
+ this.__bridgeInstance.destroy();
489
+ this.__bridgeInstance = null;
490
+ }
491
+ }
492
+ });
493
+ }
494
+ //#endregion
495
+ //#region src/bridge/drivers/angular.ts
496
+ /**
497
+ * Creates an Angular driver for a bridge component.
498
+ * Returns an Angular module that declares a component which:
499
+ * - On ngOnInit: creates bridge instance, renders into host element
500
+ * - On ngDoCheck: calls updateProps when props change
501
+ * - On ngOnDestroy: calls destroy
502
+ */
503
+ function createAngularDriver(ComponentClass) {
504
+ return ({ Component: AngularComponent, NgModule, ElementRef, NgZone, Inject }) => {
505
+ class ComponentInstance {
506
+ constructor(elementRef, zone) {
507
+ this.props = {};
508
+ this.__bridgeInstance = null;
509
+ this._prevProps = {};
510
+ this.elementRef = elementRef;
511
+ this.zone = zone;
512
+ }
513
+ getProps() {
514
+ const wrapped = { ...this.props };
515
+ const { zone } = this;
516
+ for (const [key, value] of Object.entries(wrapped)) if (typeof value === "function") wrapped[key] = function angularZoneWrapped(...args) {
517
+ return zone.run(() => value.apply(this, args));
518
+ };
519
+ return wrapped;
520
+ }
521
+ ngOnInit() {
522
+ const el = this.elementRef.nativeElement;
523
+ this.__bridgeInstance = new ComponentClass(this.getProps());
524
+ this.__bridgeInstance.render(el).catch(console.error);
525
+ }
526
+ ngDoCheck() {
527
+ if (this.__bridgeInstance && !shallowEqual(this._prevProps, this.props)) {
528
+ this._prevProps = { ...this.props };
529
+ this.__bridgeInstance.updateProps(this.getProps()).catch(() => {});
530
+ }
531
+ }
532
+ ngOnDestroy() {
533
+ if (this.__bridgeInstance) {
534
+ this.__bridgeInstance.destroy();
535
+ this.__bridgeInstance = null;
536
+ }
537
+ }
538
+ }
539
+ ComponentInstance.parameters = [[new Inject(ElementRef)], [new Inject(NgZone)]];
540
+ ComponentInstance.annotations = [new AngularComponent({
541
+ selector: ComponentClass.prototype.__options?.tag || "bridge-component",
542
+ template: "<div></div>",
543
+ inputs: ["props"]
544
+ })];
545
+ class ModuleInstance {}
546
+ ModuleInstance.annotations = [new NgModule({
547
+ declarations: [ComponentInstance],
548
+ exports: [ComponentInstance]
549
+ })];
550
+ return ModuleInstance;
551
+ };
552
+ }
553
+ function shallowEqual(a, b) {
554
+ const keysA = Object.keys(a);
555
+ const keysB = Object.keys(b);
556
+ if (keysA.length !== keysB.length) return false;
557
+ for (const key of keysA) if (a[key] !== b[key]) return false;
558
+ return true;
559
+ }
560
+ //#endregion
561
+ //#region src/bridge/drivers/index.ts
562
+ const driverFactories = {
563
+ react: createReactDriver,
564
+ vue3: createVue3Driver,
565
+ angular: createAngularDriver
566
+ };
567
+ /**
568
+ * Resolve a framework driver for a bridge component constructor.
569
+ * Called by both the static and instance .driver() methods.
570
+ */
571
+ function resolveDriver(name, ComponentClass, deps) {
572
+ const factory = driverFactories[name];
573
+ if (!factory) throw new Error(`Unknown driver: ${name}. Available: ${Object.keys(driverFactories).join(", ")}`);
574
+ return factory(ComponentClass)(deps);
575
+ }
576
+ //#endregion
577
+ //#region ../shared/lib/bridge-constants.ts
578
+ /** Protocol identifier for sync bootstrap messages between parent and child bridges */
579
+ const BRIDGE_INIT_MSG = "__monei_bridge_init__";
580
+ //#endregion
581
+ //#region src/bridge/constants.ts
582
+ /** Bridge lifecycle events (replaces zoid.EVENT) */
583
+ const EVENT = {
584
+ RENDERED: "RENDERED",
585
+ RESIZE: "RESIZE",
586
+ DESTROY: "DESTROY",
587
+ BEFORE_CLOSE: "BEFORE_CLOSE",
588
+ DISPLAY: "DISPLAY"
589
+ };
590
+ /**
591
+ * Lifecycle prop names filtered from dispatch.
592
+ * These are wired to bridge events, NOT forwarded to child.
593
+ *
594
+ * NOTE: onError, onFocus, onLoad are NOT here — they are user-facing
595
+ * props that merchants pass and children call.
596
+ */
597
+ const LIFECYCLE_PROPS = new Set([
598
+ "onClose",
599
+ "onDestroy",
600
+ "onRendered",
601
+ "onRender",
602
+ "onDisplay",
603
+ "onResize",
604
+ "onProps"
605
+ ]);
606
+ //#endregion
607
+ //#region src/bridge/props.ts
608
+ /**
609
+ * DOM utility: remove element from DOM.
610
+ * Replaces belter.destroyElement().
611
+ */
612
+ function destroyElement(el) {
613
+ if (el) el.remove();
614
+ }
615
+ /**
616
+ * CSS utility: convert number to CSS pixel string, pass strings through.
617
+ * Replaces belter.toCSS().
618
+ */
619
+ function toCSS(value) {
620
+ return typeof value === "number" ? `${value}px` : value;
621
+ }
622
+ //#endregion
623
+ //#region src/bridge/render.ts
624
+ /** Per-component iframe sandbox attributes — least-privilege per component */
625
+ const SANDBOX = {
626
+ "monei-card-input": "allow-scripts allow-forms allow-same-origin",
627
+ "monei-bizum": "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox",
628
+ "monei-bizum-button": "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox",
629
+ "monei-paypal": "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox",
630
+ "monei-payment-request": "allow-scripts allow-forms allow-same-origin allow-popups",
631
+ "monei-payment-modal": "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox",
632
+ "monei-google-pay": "allow-scripts allow-forms allow-same-origin allow-popups"
633
+ };
634
+ /**
635
+ * Resolve a container argument to an HTMLElement.
636
+ */
637
+ function resolveContainer(container) {
638
+ if (!container) throw new Error("render() requires a container element or selector");
639
+ if (typeof container === "string") {
640
+ const el = document.querySelector(container);
641
+ if (!el) throw new Error(`Container not found: ${container}`);
642
+ return el;
643
+ }
644
+ return container;
645
+ }
646
+ /**
647
+ * Generate a unique ID for the container element.
648
+ */
649
+ function generateUid(tag) {
650
+ return `${tag}-${Math.random().toString(36).slice(2, 9)}`;
651
+ }
652
+ /**
653
+ * Wire lifecycle props to bridge events.
654
+ * Called before containerTemplate in the render flow.
655
+ */
656
+ function wireLifecycleProps(props, event) {
657
+ const mappings = [
658
+ ["onClose", EVENT.DESTROY],
659
+ ["onDestroy", EVENT.DESTROY],
660
+ ["onRendered", EVENT.RENDERED],
661
+ ["onResize", EVENT.RESIZE]
662
+ ];
663
+ for (const [propKey, eventName] of mappings) event.on(eventName, (...args) => {
664
+ const fn = props[propKey];
665
+ if (typeof fn === "function") fn(...args);
666
+ });
667
+ }
668
+ /**
669
+ * Execute computed prop factories and classify remaining user props into
670
+ * dispatch map (functions) and data payload (everything else).
671
+ * Called AFTER containerTemplate so computed factories see state mutations.
672
+ */
673
+ function buildDataPayload(context) {
674
+ const { props, options, state, dispatchMap } = context;
675
+ const dataProps = {};
676
+ const computedPropKeys = new Set(options.computedProps ? Object.keys(options.computedProps) : []);
677
+ if (options.computedProps) for (const [key, config] of Object.entries(options.computedProps)) {
678
+ const result = config.factory({
679
+ props,
680
+ state
681
+ });
682
+ if (config.type === "function") dispatchMap.set(key, result);
683
+ else dataProps[key] = result;
684
+ }
685
+ for (const [key, value] of Object.entries(props)) {
686
+ if (LIFECYCLE_PROPS.has(key) || computedPropKeys.has(key)) continue;
687
+ if (typeof value === "function") dispatchMap.set(key, value);
688
+ else dataProps[key] = value;
689
+ }
690
+ const builtins = new Set([
691
+ "close",
692
+ "resize",
693
+ "show",
694
+ "hide",
695
+ "getParentDomain",
696
+ "focus"
697
+ ]);
698
+ return {
699
+ dataProps,
700
+ functionNames: [...dispatchMap.keys()].filter((k) => !builtins.has(k))
701
+ };
702
+ }
703
+ /**
704
+ * Implements .render(), .updateProps(), .destroy(), .close() on a bridge component instance.
705
+ * Called once from createComponent to wire up the actual rendering logic.
706
+ */
707
+ function attachRenderMethods(instance, options) {
708
+ const renderState = {
709
+ dispatchMap: /* @__PURE__ */ new Map(),
710
+ connection: null,
711
+ remote: null,
712
+ containerEl: null,
713
+ frame: null,
714
+ destroyed: false,
715
+ ownsContainer: false,
716
+ pendingPropsUpdate: null,
717
+ pendingRemovals: /* @__PURE__ */ new Set()
718
+ };
719
+ let renderedTriggered = false;
720
+ let lifecycleWired = false;
721
+ renderState.dispatchMap.set("resize", (dimensions) => {
722
+ const { autoResize } = options;
723
+ const applied = {};
724
+ if (dimensions.width !== void 0 && (!autoResize || autoResize.width === true)) applied.width = dimensions.width;
725
+ if (dimensions.height !== void 0 && (!autoResize || autoResize.height === true)) applied.height = dimensions.height;
726
+ if (renderState.frame) {
727
+ if (applied.width !== void 0) renderState.frame.style.width = toCSS(applied.width);
728
+ if (applied.height !== void 0) renderState.frame.style.height = toCSS(applied.height);
729
+ }
730
+ if (!renderedTriggered) {
731
+ renderedTriggered = true;
732
+ instance.event.trigger(EVENT.RENDERED);
733
+ }
734
+ instance.event.trigger(EVENT.RESIZE, applied);
735
+ });
736
+ renderState.dispatchMap.set("close", () => instance.close());
737
+ renderState.dispatchMap.set("show", () => {
738
+ if (renderState.frame) renderState.frame.style.display = "";
739
+ });
740
+ renderState.dispatchMap.set("hide", () => {
741
+ if (renderState.frame) renderState.frame.style.display = "none";
742
+ });
743
+ renderState.dispatchMap.set("getParentDomain", () => window.location.origin);
744
+ renderState.dispatchMap.set("focus", () => {
745
+ if (renderState.frame) renderState.frame.focus();
746
+ });
747
+ /**
748
+ * Render the component into the DOM and establish Penpal connection.
749
+ *
750
+ * Phase ordering:
751
+ * 1. wireLifecycleProps — bind onClose/onRendered/onResize to bridge events
752
+ * 2. prerenderTemplate — create loading placeholder (optional)
753
+ * 3. containerTemplate — build wrapper DOM, may mutate `state` (e.g., state.__container for PayPal)
754
+ * 4. buildDataPayload — run computed prop factories (read state mutations from step 3),
755
+ * classify user props into dispatch map (functions) and data payload (serializable values)
756
+ * 5. appendToDOM — container or bare iframe inserted into target element
757
+ * 6. triggerDISPLAY — notify container template that DOM is ready
758
+ * 7. sendBootstrap — postMessage initial props to iframe before script loads
759
+ * 8. createConnection — establish Penpal async RPC channel, deliver props via updateProps
760
+ */
761
+ instance.render = async (container) => {
762
+ if (renderState.destroyed) throw new Error("Component is destroyed");
763
+ if (renderState.frame) throw new Error("Component already rendered");
764
+ const targetEl = resolveContainer(container);
765
+ const uid = generateUid(options.tag);
766
+ const doc = targetEl.ownerDocument;
767
+ const frame = doc.createElement("iframe");
768
+ frame.src = options.url;
769
+ frame.setAttribute("title", options.tag.replace(/-/g, "_"));
770
+ frame.setAttribute("allowpaymentrequest", "true");
771
+ frame.setAttribute("allow", "payment");
772
+ frame.style.border = "none";
773
+ const sandbox = SANDBOX[options.tag] ?? "allow-scripts allow-forms allow-same-origin";
774
+ frame.setAttribute("sandbox", sandbox);
775
+ if (!lifecycleWired) {
776
+ wireLifecycleProps(instance.props, instance.event);
777
+ lifecycleWired = true;
778
+ }
779
+ const templateSubs = [];
780
+ const trackedEvent = {
781
+ on(eventName, handler) {
782
+ const sub = instance.event.on(eventName, handler);
783
+ templateSubs.push(sub);
784
+ return sub;
785
+ },
786
+ once(eventName, handler) {
787
+ const sub = instance.event.once(eventName, handler);
788
+ templateSubs.push(sub);
789
+ return sub;
790
+ },
791
+ trigger(eventName, ...args) {
792
+ instance.event.trigger(eventName, ...args);
793
+ },
794
+ off(eventName, handler) {
795
+ instance.event.off(eventName, handler);
796
+ },
797
+ destroy() {
798
+ instance.event.destroy();
799
+ }
800
+ };
801
+ let placeholder;
802
+ let containerNode;
803
+ let dataProps = {};
804
+ let functionNames = [];
805
+ try {
806
+ if (options.prerenderTemplate) placeholder = options.prerenderTemplate({
807
+ uid,
808
+ frame,
809
+ placeholder: void 0,
810
+ doc,
811
+ props: instance.props,
812
+ event: trackedEvent,
813
+ dimensions: options.dimensions ?? {
814
+ width: "100%",
815
+ height: "auto"
816
+ },
817
+ state: instance.state,
818
+ container: targetEl
819
+ });
820
+ if (options.containerTemplate) containerNode = options.containerTemplate({
821
+ uid,
822
+ frame,
823
+ placeholder,
824
+ doc,
825
+ props: instance.props,
826
+ event: trackedEvent,
827
+ dimensions: options.dimensions ?? {
828
+ width: "100%",
829
+ height: "auto"
830
+ },
831
+ state: instance.state,
832
+ container: targetEl
833
+ });
834
+ ({dataProps, functionNames} = buildDataPayload({
835
+ props: instance.props,
836
+ options,
837
+ state: instance.state,
838
+ dispatchMap: renderState.dispatchMap
839
+ }));
840
+ } catch (err) {
841
+ for (const sub of templateSubs) sub.cancel();
842
+ const builtins = new Set([
843
+ "close",
844
+ "resize",
845
+ "show",
846
+ "hide",
847
+ "getParentDomain",
848
+ "focus"
849
+ ]);
850
+ for (const key of renderState.dispatchMap.keys()) if (!builtins.has(key)) renderState.dispatchMap.delete(key);
851
+ throw err;
852
+ }
853
+ renderState.frame = frame;
854
+ const sendInitialProps = () => {
855
+ if (frame.contentWindow) frame.contentWindow.postMessage({
856
+ type: BRIDGE_INIT_MSG,
857
+ props: dataProps,
858
+ functionNames
859
+ }, new URL(options.url).origin);
860
+ };
861
+ try {
862
+ if (containerNode) {
863
+ targetEl.appendChild(containerNode);
864
+ renderState.containerEl = containerNode;
865
+ renderState.ownsContainer = true;
866
+ } else {
867
+ targetEl.appendChild(frame);
868
+ renderState.containerEl = targetEl;
869
+ }
870
+ instance.event.trigger(EVENT.DISPLAY);
871
+ frame.addEventListener("load", sendInitialProps);
872
+ if (frame.contentWindow) sendInitialProps();
873
+ if (!frame.contentWindow) throw new Error("iframe contentWindow is not available — frame may not be in the DOM");
874
+ const connection = connect({
875
+ messenger: new WindowMessenger({
876
+ remoteWindow: frame.contentWindow,
877
+ allowedOrigins: [new URL(options.url).origin]
878
+ }),
879
+ methods: { callParent: (name, args) => {
880
+ const fn = renderState.dispatchMap.get(name);
881
+ if (!fn) throw new Error(`Unknown parent method: ${name}`);
882
+ return fn(...args);
883
+ } }
884
+ });
885
+ renderState.connection = connection;
886
+ let remote;
887
+ try {
888
+ remote = await connection.promise;
889
+ } catch (err) {
890
+ if (renderState.destroyed) return;
891
+ throw err;
892
+ }
893
+ if (renderState.destroyed) return;
894
+ renderState.remote = remote;
895
+ instance.state.__callChild = remote.callChild;
896
+ await remote.updateProps(dataProps, functionNames);
897
+ if (renderState.destroyed) return;
898
+ if (renderState.pendingPropsUpdate) {
899
+ const pending = renderState.pendingPropsUpdate;
900
+ renderState.pendingPropsUpdate = null;
901
+ const retainedFns = new Set(pending.functionNames ?? []);
902
+ const flushRemovals = /* @__PURE__ */ new Map();
903
+ for (const key of Object.keys(pending.dataProps)) if (renderState.dispatchMap.has(key) && !retainedFns.has(key)) {
904
+ flushRemovals.set(key, renderState.dispatchMap.get(key));
905
+ renderState.pendingRemovals.add(key);
906
+ }
907
+ await renderState.remote.updateProps(pending.dataProps, pending.functionNames);
908
+ if (renderState.destroyed) return;
909
+ for (const [key, originalFn] of flushRemovals) {
910
+ renderState.pendingRemovals.delete(key);
911
+ if (renderState.dispatchMap.get(key) === originalFn) renderState.dispatchMap.delete(key);
912
+ }
913
+ }
914
+ if (!renderedTriggered) {
915
+ renderedTriggered = true;
916
+ instance.event.trigger(EVENT.RENDERED);
917
+ }
918
+ frame.removeEventListener("load", sendInitialProps);
919
+ } catch (err) {
920
+ frame.removeEventListener("load", sendInitialProps);
921
+ for (const sub of templateSubs) sub.cancel();
922
+ delete instance.state.__callChild;
923
+ if (renderState.connection) {
924
+ renderState.connection.destroy();
925
+ renderState.connection = null;
926
+ }
927
+ renderState.remote = null;
928
+ renderState.frame = null;
929
+ if (renderState.ownsContainer && renderState.containerEl) renderState.containerEl.remove();
930
+ else if (frame.parentNode) frame.remove();
931
+ renderState.containerEl = null;
932
+ renderState.ownsContainer = false;
933
+ renderState.pendingPropsUpdate = null;
934
+ renderState.pendingRemovals.clear();
935
+ const builtins = new Set([
936
+ "close",
937
+ "resize",
938
+ "show",
939
+ "hide",
940
+ "getParentDomain",
941
+ "focus"
942
+ ]);
943
+ for (const key of renderState.dispatchMap.keys()) if (!builtins.has(key)) renderState.dispatchMap.delete(key);
944
+ renderedTriggered = false;
945
+ throw err;
946
+ }
947
+ };
948
+ instance.updateProps = async (newProps) => {
949
+ if (renderState.destroyed) throw new Error("Component is destroyed");
950
+ const normalized = normalizeAliases(newProps, options.aliases);
951
+ Object.assign(instance.props, normalized);
952
+ if (!renderState.frame) return;
953
+ const newDataProps = {};
954
+ const newFunctionNames = [];
955
+ const computedPropKeys = new Set(options.computedProps ? Object.keys(options.computedProps) : []);
956
+ const deferredRemovals = /* @__PURE__ */ new Map();
957
+ for (const [key, value] of Object.entries(normalized)) {
958
+ if (LIFECYCLE_PROPS.has(key) || computedPropKeys.has(key)) continue;
959
+ if (typeof value === "function") {
960
+ const hasStaleBufferedData = renderState.pendingPropsUpdate != null && key in renderState.pendingPropsUpdate.dataProps;
961
+ const hasPendingRemoval = renderState.pendingRemovals.has(key);
962
+ if (!renderState.dispatchMap.has(key) || hasStaleBufferedData || hasPendingRemoval) newFunctionNames.push(key);
963
+ renderState.dispatchMap.set(key, value);
964
+ } else {
965
+ if (renderState.dispatchMap.has(key)) {
966
+ if (renderState.remote) {
967
+ deferredRemovals.set(key, renderState.dispatchMap.get(key));
968
+ renderState.pendingRemovals.add(key);
969
+ }
970
+ }
971
+ newDataProps[key] = value;
972
+ }
973
+ }
974
+ const resolvedFunctionNames = newFunctionNames.length > 0 ? newFunctionNames : void 0;
975
+ if (renderState.remote) {
976
+ await renderState.remote.updateProps(newDataProps, resolvedFunctionNames);
977
+ for (const [key, originalFn] of deferredRemovals) {
978
+ renderState.pendingRemovals.delete(key);
979
+ if (renderState.dispatchMap.get(key) === originalFn) renderState.dispatchMap.delete(key);
980
+ }
981
+ } else {
982
+ if (!renderState.pendingPropsUpdate) renderState.pendingPropsUpdate = {
983
+ dataProps: {},
984
+ functionNames: void 0
985
+ };
986
+ Object.assign(renderState.pendingPropsUpdate.dataProps, newDataProps);
987
+ if (renderState.pendingPropsUpdate.functionNames) {
988
+ const dataKeys = Object.keys(newDataProps);
989
+ if (dataKeys.length > 0) {
990
+ const dataKeySet = new Set(dataKeys);
991
+ renderState.pendingPropsUpdate.functionNames = renderState.pendingPropsUpdate.functionNames.filter((n) => !dataKeySet.has(n));
992
+ if (renderState.pendingPropsUpdate.functionNames.length === 0) renderState.pendingPropsUpdate.functionNames = void 0;
993
+ }
994
+ }
995
+ if (resolvedFunctionNames) {
996
+ for (const name of resolvedFunctionNames) delete renderState.pendingPropsUpdate.dataProps[name];
997
+ renderState.pendingPropsUpdate.functionNames = [...renderState.pendingPropsUpdate.functionNames ?? [], ...resolvedFunctionNames];
998
+ }
999
+ }
1000
+ };
1001
+ instance.destroy = async () => {
1002
+ if (renderState.destroyed) return;
1003
+ renderState.destroyed = true;
1004
+ instance.event.trigger(EVENT.DESTROY);
1005
+ if (renderState.connection) {
1006
+ renderState.connection.destroy();
1007
+ renderState.connection = null;
1008
+ }
1009
+ renderState.remote = null;
1010
+ if (renderState.frame) {
1011
+ renderState.frame.remove();
1012
+ renderState.frame = null;
1013
+ }
1014
+ if (renderState.ownsContainer && renderState.containerEl) renderState.containerEl.remove();
1015
+ instance.event.destroy();
1016
+ renderState.dispatchMap.clear();
1017
+ };
1018
+ instance.close = async () => {
1019
+ await instance.destroy();
1020
+ };
1021
+ /**
1022
+ * Expose renderState for tests
1023
+ */
1024
+ instance.__renderState = renderState;
1025
+ }
1026
+ //#endregion
1027
+ //#region src/bridge/create-component.ts
1028
+ /**
1029
+ * Normalize aliased prop names to canonical names.
1030
+ * Aliases define alternative INPUT names: { style: 'innerStyle' } means
1031
+ * merchants can pass either `style` or `innerStyle`, but internally
1032
+ * the canonical name `style` is always used (matching zoid semantics).
1033
+ */
1034
+ function normalizeAliases(props, aliases) {
1035
+ if (!aliases) return props;
1036
+ const reverseMap = /* @__PURE__ */ new Map();
1037
+ for (const [canonical, alias] of Object.entries(aliases)) reverseMap.set(alias, canonical);
1038
+ const result = {};
1039
+ for (const [key, value] of Object.entries(props)) {
1040
+ const canonicalKey = reverseMap.get(key) ?? key;
1041
+ result[canonicalKey] = value;
1042
+ }
1043
+ return result;
1044
+ }
1045
+ /**
1046
+ * Creates a bridge component constructor (replaces zoid.create).
1047
+ *
1048
+ * Returns a class that can be instantiated with `new Component(props)`
1049
+ * and has a static `.driver()` method for framework wrappers.
1050
+ */
1051
+ function createComponent(options) {
1052
+ class Component {
1053
+ constructor(props) {
1054
+ this.state = {};
1055
+ this.event = new EventEmitter();
1056
+ const normalizedProps = normalizeAliases(props, options.aliases);
1057
+ if (options.defaultProps) this.props = {
1058
+ ...options.defaultProps({ event: this.event }),
1059
+ ...normalizedProps
1060
+ };
1061
+ else this.props = { ...normalizedProps };
1062
+ if (options.validate) options.validate({ props: this.props });
1063
+ attachRenderMethods(this, options);
1064
+ }
1065
+ async render(_container) {
1066
+ throw new Error("render() not attached");
1067
+ }
1068
+ async updateProps(_props) {
1069
+ throw new Error("updateProps() not attached — call render() first");
1070
+ }
1071
+ async close() {
1072
+ throw new Error("close() not attached");
1073
+ }
1074
+ async destroy() {
1075
+ throw new Error("destroy() not attached");
1076
+ }
1077
+ driver(name, deps) {
1078
+ return resolveDriver(name, Component, deps);
1079
+ }
1080
+ }
1081
+ function ComponentWrapper(props) {
1082
+ if (!(this instanceof ComponentWrapper)) return new ComponentWrapper(props);
1083
+ return new Component(props);
1084
+ }
1085
+ ComponentWrapper.prototype = Component.prototype;
1086
+ ComponentWrapper.driver = function(name, deps) {
1087
+ return resolveDriver(name, ComponentWrapper, deps);
1088
+ };
1089
+ Component.prototype.__options = options;
1090
+ return ComponentWrapper;
1091
+ }
1092
+ //#endregion
1093
+ //#region src/enums.ts
1094
+ let CLASS = /* @__PURE__ */ function(CLASS) {
1095
+ CLASS["VISIBLE"] = "is-visible";
1096
+ CLASS["INVISIBLE"] = "is-invisible";
1097
+ return CLASS;
1098
+ }({});
1099
+ //#endregion
1100
+ //#region src/container.ts
1101
+ function createContainerTemplate(config = {}) {
1102
+ const { background = "#fff", overflow, borderRadius, fadeOnRender = true, allowTransparency = false, modal = false } = config;
1103
+ return function containerTemplateFn({ uid, frame, placeholder, doc, props, event, dimensions: { width, height } }) {
1104
+ if (!frame) return;
1105
+ if (allowTransparency) {
1106
+ frame.setAttribute("allowtransparency", "true");
1107
+ frame.style.background = "transparent";
1108
+ }
1109
+ const div = doc.createElement("div");
1110
+ div.setAttribute("id", uid);
1111
+ const style = doc.createElement("style");
1112
+ if (props?.cspNonce) style.setAttribute("nonce", props.cspNonce);
1113
+ if (modal) {
1114
+ const backdrop = doc.createElement("div");
1115
+ backdrop.classList.add("backdrop");
1116
+ style.appendChild(doc.createTextNode(`
1117
+ #${uid} {
1118
+ position: fixed;
1119
+ inset: 0;
1120
+ z-index: 99999;
1121
+ }
1122
+ #${uid} > .backdrop {
1123
+ position: fixed;
1124
+ inset: 0;
1125
+ background-color: rgba(40, 40, 40, 0.7);
1126
+ opacity: 0;
1127
+ transition: opacity 0.35s ease-in-out;
1128
+ will-change: opacity;
1129
+ }
1130
+ #${uid} > .backdrop.${CLASS.VISIBLE} {
1131
+ opacity: 1;
1132
+ }
1133
+ #${uid} > iframe {
1134
+ display: block;
1135
+ position: absolute;
1136
+ width: 100%;
1137
+ height: 100%;
1138
+ top: 0;
1139
+ left: 0;
1140
+ transition: opacity .2s ease-in-out;
1141
+ }
1142
+ #${uid} > iframe.${CLASS.INVISIBLE} {
1143
+ opacity: 0;
1144
+ }
1145
+ #${uid} > iframe.${CLASS.VISIBLE} {
1146
+ opacity: 1;
1147
+ }
1148
+ `));
1149
+ div.appendChild(backdrop);
1150
+ div.appendChild(frame);
1151
+ if (placeholder) div.appendChild(placeholder);
1152
+ div.appendChild(style);
1153
+ event.on(EVENT.DISPLAY, () => {
1154
+ backdrop.offsetHeight;
1155
+ requestAnimationFrame(() => backdrop.classList.add(CLASS.VISIBLE));
1156
+ });
1157
+ event.on(EVENT.BEFORE_CLOSE, () => {
1158
+ backdrop.classList.remove(CLASS.VISIBLE);
1159
+ });
1160
+ frame.classList.add(CLASS.INVISIBLE);
1161
+ if (fadeOnRender && placeholder) placeholder.classList.add(CLASS.VISIBLE);
1162
+ event.on(EVENT.RENDERED, () => {
1163
+ if (fadeOnRender) {
1164
+ if (placeholder) {
1165
+ placeholder.classList.remove(CLASS.VISIBLE);
1166
+ placeholder.classList.add(CLASS.INVISIBLE);
1167
+ }
1168
+ frame.classList.remove(CLASS.INVISIBLE);
1169
+ frame.classList.add(CLASS.VISIBLE);
1170
+ setTimeout(() => destroyElement(placeholder), 1);
1171
+ } else {
1172
+ if (placeholder) destroyElement(placeholder);
1173
+ frame.style.transition = "none";
1174
+ frame.classList.remove(CLASS.INVISIBLE);
1175
+ frame.classList.add(CLASS.VISIBLE);
1176
+ }
1177
+ });
1178
+ } else {
1179
+ const innerStyle = props?.style || props?.innerStyle;
1180
+ const initialHeight = height === "0" ? "0" : toCSS(innerStyle?.base?.height || innerStyle?.height || (height === "auto" ? 45 : height));
1181
+ const containerStyles = [
1182
+ "display: block",
1183
+ "position: relative",
1184
+ `width: ${width}`,
1185
+ `height: ${allowTransparency ? height : initialHeight}`,
1186
+ `background: ${background}`
1187
+ ];
1188
+ if (overflow) containerStyles.push(`overflow: ${overflow}`);
1189
+ if (borderRadius) containerStyles.push(`border-radius: ${borderRadius}`);
1190
+ style.appendChild(doc.createTextNode(`
1191
+ #${uid} {
1192
+ ${containerStyles.join(";\n ")};
1193
+ }
1194
+ #${uid} > iframe {
1195
+ display: block;
1196
+ position: absolute;
1197
+ width: 100%;
1198
+ height: 100%;
1199
+ top: 0;
1200
+ left: 0;
1201
+ transition: opacity .2s ease-in-out;
1202
+ }
1203
+ #${uid} > iframe.${CLASS.INVISIBLE} {
1204
+ opacity: 0;
1205
+ }
1206
+ #${uid} > iframe.${CLASS.VISIBLE} {
1207
+ opacity: 1;
1208
+ }
1209
+ `));
1210
+ div.appendChild(frame);
1211
+ if (placeholder) div.appendChild(placeholder);
1212
+ div.appendChild(style);
1213
+ event.on(EVENT.RESIZE, ({ width: newWidth, height: newHeight }) => {
1214
+ if (typeof newWidth === "number") div.style.width = toCSS(newWidth);
1215
+ if (typeof newHeight === "number") div.style.height = toCSS(newHeight);
1216
+ });
1217
+ if (placeholder) {
1218
+ frame.classList.add(CLASS.INVISIBLE);
1219
+ if (fadeOnRender) placeholder.classList.add(CLASS.VISIBLE);
1220
+ event.on(EVENT.RENDERED, () => {
1221
+ if (fadeOnRender) {
1222
+ placeholder.classList.remove(CLASS.VISIBLE);
1223
+ placeholder.classList.add(CLASS.INVISIBLE);
1224
+ frame.classList.remove(CLASS.INVISIBLE);
1225
+ frame.classList.add(CLASS.VISIBLE);
1226
+ setTimeout(() => destroyElement(placeholder), 1);
1227
+ } else {
1228
+ destroyElement(placeholder);
1229
+ frame.style.transition = "none";
1230
+ frame.classList.remove(CLASS.INVISIBLE);
1231
+ frame.classList.add(CLASS.VISIBLE);
1232
+ }
1233
+ });
1234
+ }
1235
+ }
1236
+ return div;
1237
+ };
1238
+ }
1239
+ const containerTemplate = createContainerTemplate({
1240
+ overflow: "hidden",
1241
+ borderRadius: "var(--monei-radius, 4px)"
1242
+ });
1243
+ const modalContainerTemplate = createContainerTemplate({ modal: true });
1244
+ //#endregion
1245
+ //#region src/card-input/index.ts
1246
+ const getCreateTokenFunction = (ref) => {
1247
+ if (ref.state?.__createToken) return ref.state.__createToken;
1248
+ throw new Error("Index is not registered");
1249
+ };
1250
+ const createToken = async (component, options) => {
1251
+ const { data } = await getCreateTokenFunction(component)(options);
1252
+ return data;
1253
+ };
1254
+ const CardInput = createComponent({
1255
+ tag: "monei-card-input",
1256
+ url: config.cardInputUrl,
1257
+ dimensions: {
1258
+ width: "100%",
1259
+ height: "auto"
1260
+ },
1261
+ autoResize: {
1262
+ width: false,
1263
+ height: true
1264
+ },
1265
+ aliases: {
1266
+ sessionId: "orderId",
1267
+ style: "innerStyle"
1268
+ },
1269
+ computedProps: { __getConfig: {
1270
+ factory: ({ props }) => getPaymentMethods.bind(null, props),
1271
+ type: "function"
1272
+ } },
1273
+ validate: validateComponentProps,
1274
+ containerTemplate: (params) => {
1275
+ params.state.__createToken = async (data = {}) => {
1276
+ const callChild = params.state.__callChild;
1277
+ if (!callChild) throw new Error("CardInput instance is not registered");
1278
+ return { data: await callChild("createToken", [data]) };
1279
+ };
1280
+ return containerTemplate(params);
1281
+ },
1282
+ prerenderTemplate: ({ doc, props }) => {
1283
+ const html = doc.createElement("html");
1284
+ const body = doc.createElement("body");
1285
+ body.style.margin = "0";
1286
+ body.style.background = "#fff";
1287
+ const div = doc.createElement("div");
1288
+ div.style.height = "45px";
1289
+ div.style.boxSizing = "border-box";
1290
+ const style = props.style || props.innerStyle;
1291
+ if (style?.base) Object.assign(div.style, transformStyle(style.base));
1292
+ if (style?.loading) Object.assign(div.style, transformStyle(style.loading));
1293
+ body.appendChild(div);
1294
+ html.appendChild(body);
1295
+ return html;
1296
+ }
1297
+ });
1298
+ const PaymentModal = createComponent({
1299
+ tag: "monei-payment-modal",
1300
+ url: config.paymentModalUrl,
1301
+ dimensions: {
1302
+ width: "100%",
1303
+ height: "100%"
1304
+ },
1305
+ autoResize: {
1306
+ width: false,
1307
+ height: false
1308
+ },
1309
+ aliases: { style: "innerStyle" },
1310
+ containerTemplate: createContainerTemplate({
1311
+ background: "transparent",
1312
+ fadeOnRender: false,
1313
+ allowTransparency: true
1314
+ })
1315
+ });
1316
+ const confirmPayment = (params) => {
1317
+ const rootNode = document.createElement("div");
1318
+ const bodyOverflow = document.body.style.overflow;
1319
+ Object.assign(document.body.style, { overflow: "hidden" });
1320
+ Object.assign(rootNode.style, {
1321
+ position: "fixed",
1322
+ overflow: "hidden",
1323
+ display: "block",
1324
+ top: "0",
1325
+ bottom: "0",
1326
+ left: "0",
1327
+ right: "0",
1328
+ width: "100%",
1329
+ height: "100%",
1330
+ zIndex: "99999"
1331
+ });
1332
+ document.body.appendChild(rootNode);
1333
+ let modal = null;
1334
+ const cleanup = () => {
1335
+ modal?.destroy();
1336
+ modal = null;
1337
+ Object.assign(document.body.style, { overflow: bodyOverflow });
1338
+ if (rootNode.parentNode) rootNode.parentNode.removeChild(rootNode);
1339
+ };
1340
+ return new Promise((resolve, reject) => {
1341
+ modal = new PaymentModal({
1342
+ ...params,
1343
+ isOpen: true,
1344
+ onResult: (result) => {
1345
+ resolve(result);
1346
+ cleanup();
1347
+ },
1348
+ onError: (error) => {
1349
+ reject(error);
1350
+ cleanup();
1351
+ }
1352
+ });
1353
+ modal.render(rootNode).catch((err) => {
1354
+ cleanup();
1355
+ reject(err);
1356
+ });
1357
+ });
1358
+ };
1359
+ //#endregion
1360
+ //#region src/paypal/index.ts
1361
+ const namespace = "monei-paypal";
1362
+ const onLoadPaypal = async (props, state, src) => {
1363
+ state.__scriptId = (await loadScript(src, props.cspNonce, {
1364
+ namespace,
1365
+ cspNonce: props.cspNonce
1366
+ }, true)).dataset.uidAuto;
1367
+ const defaultStyle = {
1368
+ layout: "horizontal",
1369
+ tagline: false,
1370
+ height: 45
1371
+ };
1372
+ const radius = parsePx(props.style?.borderRadius ?? props.borderRadius);
1373
+ if (radius) defaultStyle.borderRadius = radius;
1374
+ const style = {
1375
+ ...defaultStyle,
1376
+ ...props.style
1377
+ };
1378
+ style.height = parsePx(style.height, 45);
1379
+ props.onLoad?.(true);
1380
+ let token;
1381
+ await window[namespace].Buttons({
1382
+ createOrder: async () => {
1383
+ try {
1384
+ const result = await createToken$1({
1385
+ paymentId: props.paymentId,
1386
+ accountId: props.accountId,
1387
+ sessionId: props.sessionId,
1388
+ amount: props.amount,
1389
+ currency: props.currency,
1390
+ transactionType: props.transactionType,
1391
+ paymentMethod: { paypal: {} }
1392
+ });
1393
+ ({token} = result);
1394
+ return result.paypal?.orderId;
1395
+ } catch (error) {
1396
+ props.onError?.(error);
1397
+ return;
1398
+ }
1399
+ },
1400
+ onApprove: function(data) {
1401
+ if (data.orderID) props.onSubmit({ token });
1402
+ else props.onError?.(data);
1403
+ },
1404
+ onClick: function(_data, actions) {
1405
+ let shouldOpen = true;
1406
+ if (props.onBeforeOpen) shouldOpen = props.onBeforeOpen();
1407
+ if (!shouldOpen) return actions.reject();
1408
+ },
1409
+ style
1410
+ }).render(state.__container);
1411
+ };
1412
+ const PayPal = createComponent({
1413
+ tag: namespace,
1414
+ url: config.paypalUrl,
1415
+ dimensions: {
1416
+ width: "100%",
1417
+ height: "0"
1418
+ },
1419
+ autoResize: {
1420
+ width: false,
1421
+ height: false
1422
+ },
1423
+ aliases: { style: "innerStyle" },
1424
+ computedProps: {
1425
+ __getConfig: {
1426
+ factory: ({ props }) => getPaymentMethods.bind(null, props),
1427
+ type: "function"
1428
+ },
1429
+ __onLoadPayPal: {
1430
+ factory: ({ props, state }) => onLoadPaypal.bind(null, props, state),
1431
+ type: "function"
1432
+ }
1433
+ },
1434
+ containerTemplate: (params) => {
1435
+ params.state.__container = params.container;
1436
+ if (!params.props.accountId && !params.props.paymentId) throw new Error("You need to provide paymentId or accountId");
1437
+ const container = containerTemplate(params);
1438
+ params.event.on(EVENT.DESTROY, () => {
1439
+ window[namespace]?.Buttons?.instances?.forEach((instance) => {
1440
+ instance.close();
1441
+ });
1442
+ const scriptId = params.state.__scriptId;
1443
+ if (scriptId) {
1444
+ const script = document.querySelector(`script[data-uid-auto="${scriptId}"]`);
1445
+ if (script) script.remove();
1446
+ }
1447
+ });
1448
+ return container;
1449
+ }
1450
+ });
1451
+ const BizumModal = createComponent({
1452
+ tag: "monei-bizum",
1453
+ url: config.bizumUrl,
1454
+ autoResize: {
1455
+ width: false,
1456
+ height: false
1457
+ },
1458
+ containerTemplate: (params) => {
1459
+ if (!params.frame) return;
1460
+ if (params.props.isHidden) {
1461
+ const div = params.doc.createElement("div");
1462
+ div.setAttribute("id", params.uid);
1463
+ div.style.display = "none";
1464
+ div.appendChild(params.frame);
1465
+ if (params.placeholder) div.appendChild(params.placeholder);
1466
+ return div;
1467
+ }
1468
+ return modalContainerTemplate(params);
1469
+ },
1470
+ defaultProps: ({ event }) => ({ onBeforeClose: () => {
1471
+ event.trigger(EVENT.BEFORE_CLOSE);
1472
+ } })
1473
+ });
1474
+ const Bizum = createComponent({
1475
+ tag: "monei-bizum-button",
1476
+ url: config.bizumButtonUrl,
1477
+ dimensions: {
1478
+ width: "100%",
1479
+ height: "auto"
1480
+ },
1481
+ autoResize: {
1482
+ width: false,
1483
+ height: true
1484
+ },
1485
+ aliases: { style: "innerStyle" },
1486
+ computedProps: {
1487
+ __getConfig: {
1488
+ factory: ({ props }) => getPaymentMethods.bind(null, props),
1489
+ type: "function"
1490
+ },
1491
+ __onClick: {
1492
+ factory: ({ props, state }) => {
1493
+ const rootNode = document.createElement("div");
1494
+ return ({ amount, currency }) => {
1495
+ if (state.isOpen) return;
1496
+ let shouldOpen = true;
1497
+ if (props.onBeforeOpen) shouldOpen = props.onBeforeOpen();
1498
+ if (!shouldOpen) return;
1499
+ state.isOpen = true;
1500
+ if (!rootNode.parentNode) document.body.appendChild(rootNode);
1501
+ const bizumModal = new BizumModal({
1502
+ amount,
1503
+ currency,
1504
+ ...props,
1505
+ onClose: () => {
1506
+ state.isOpen = false;
1507
+ window.onpopstate = null;
1508
+ document.body.style.overflow = "";
1509
+ },
1510
+ isOpen: true
1511
+ });
1512
+ window.history.pushState(null, "", window.location.href);
1513
+ window.onpopstate = () => bizumModal.updateProps({ isOpen: false });
1514
+ Object.assign(document.body.style, { overflow: "hidden" });
1515
+ return bizumModal.render(rootNode);
1516
+ };
1517
+ },
1518
+ type: "function"
1519
+ }
1520
+ },
1521
+ validate: validateComponentProps,
1522
+ containerTemplate
1523
+ });
1524
+ const GooglePay = createComponent({
1525
+ tag: "monei-google-pay",
1526
+ url: config.paymentRequestUrl,
1527
+ dimensions: {
1528
+ width: "100%",
1529
+ height: "0"
1530
+ },
1531
+ autoResize: {
1532
+ width: false,
1533
+ height: true
1534
+ },
1535
+ aliases: { style: "innerStyle" },
1536
+ computedProps: { __getConfig: {
1537
+ factory: ({ props }) => getPaymentMethods.bind(null, props),
1538
+ type: "function"
1539
+ } },
1540
+ validate: validateComponentProps,
1541
+ containerTemplate
1542
+ });
1543
+ const PaymentRequest = createComponent({
1544
+ tag: "monei-payment-request",
1545
+ url: config.paymentRequestUrl,
1546
+ dimensions: {
1547
+ width: "100%",
1548
+ height: "auto"
1549
+ },
1550
+ autoResize: {
1551
+ width: false,
1552
+ height: true
1553
+ },
1554
+ aliases: { style: "innerStyle" },
1555
+ computedProps: { __getConfig: {
1556
+ factory: ({ props }) => getPaymentMethods.bind(null, props),
1557
+ type: "function"
1558
+ } },
1559
+ validate: validateComponentProps,
1560
+ containerTemplate
1561
+ });
1562
+ //#endregion
1563
+ //#region src/types.ts
1564
+ let NextActionType = /* @__PURE__ */ function(NextActionType) {
1565
+ NextActionType["CONFIRM"] = "CONFIRM";
1566
+ NextActionType["FRICTIONLESS_CHALLENGE"] = "FRICTIONLESS_CHALLENGE";
1567
+ NextActionType["BIZUM_CHALLENGE"] = "BIZUM_CHALLENGE";
1568
+ NextActionType["CHALLENGE"] = "CHALLENGE";
1569
+ NextActionType["COMPLETE"] = "COMPLETE";
1570
+ return NextActionType;
1571
+ }({});
1572
+ let CardBrand = /* @__PURE__ */ function(CardBrand) {
1573
+ CardBrand["Visa"] = "visa";
1574
+ CardBrand["Mastercard"] = "mastercard";
1575
+ CardBrand["Amex"] = "amex";
1576
+ CardBrand["Discover"] = "discover";
1577
+ CardBrand["Diners"] = "diners";
1578
+ CardBrand["JCB"] = "jcb";
1579
+ CardBrand["Maestro"] = "maestro";
1580
+ CardBrand["UnionPay"] = "unionpay";
1581
+ CardBrand["Elo"] = "elo";
1582
+ CardBrand["Hipercard"] = "hipercard";
1583
+ return CardBrand;
1584
+ }({});
1585
+ let TransactionType = /* @__PURE__ */ function(TransactionType) {
1586
+ TransactionType["AUTH"] = "AUTH";
1587
+ TransactionType["SALE"] = "SALE";
1588
+ TransactionType["PAYOUT"] = "PAYOUT";
1589
+ TransactionType["VERIF"] = "VERIF";
1590
+ return TransactionType;
1591
+ }({});
1592
+ //#endregion
1593
+ //#region src/index.ts
1594
+ const api = api_exports;
1595
+ const utils = utils_exports;
1596
+ //#endregion
1597
+ export { Bizum, BizumModal, CardBrand, CardInput, GooglePay, NextActionType, PayPal, PaymentModal, PaymentRequest, TransactionType, api, config, confirmPayment, createToken, utils };