@pybara/pybara-js 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/checkout.schema.json +2 -1
- package/dist/button/button.d.ts +39 -0
- package/dist/button/button.d.ts.map +1 -0
- package/dist/button/index.d.ts +12 -0
- package/dist/button/index.d.ts.map +1 -0
- package/dist/button/index.js +1 -0
- package/dist/button-BEOTKYpw.js +127 -0
- package/dist/checkout.d.ts.map +1 -1
- package/dist/config-9RX2E1N4.js +16 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/modal/index.js +1 -1
- package/dist/{modal-BiPk8xwF.js → modal-CXTyI_BA.js} +30 -40
- package/dist/pybara-js.iife.js +1 -1
- package/dist/pybara-js.js +63 -155
- package/dist/types.d.ts +11 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/dist/buttons.d.ts +0 -11
- package/dist/buttons.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @pybara/pybara-js
|
|
|
13
13
|
No bundler? The IIFE build exposes `window.Pybara` — the same calls as the module:
|
|
14
14
|
|
|
15
15
|
```html
|
|
16
|
-
<script src="https://cdn.jsdelivr.net/npm/@pybara/pybara-js@0.
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/@pybara/pybara-js@0.9/dist/pybara-js.iife.js"></script>
|
|
17
17
|
<script>
|
|
18
18
|
const pybara = Pybara.checkout({ siteUrl, siteName, recipientPrincipal, currency: 'EUR' });
|
|
19
19
|
pybara.buttons({ createPayment: () => ({ amount: '25' }) }).render('#pybara-button');
|
|
@@ -22,7 +22,7 @@ No bundler? The IIFE build exposes `window.Pybara` — the same calls as the mod
|
|
|
22
22
|
|
|
23
23
|
## Add Pybara next to PayPal
|
|
24
24
|
|
|
25
|
-
A page with PayPal Buttons gets a Pybara button beside them in a few lines. Pass the PayPal button's `style` as it is (`color`, `shape`, `height`) and the two match:
|
|
25
|
+
A page with PayPal Buttons gets a Pybara button beside them in a few lines. Pass the PayPal button's `style` as it is (`color`, `shape`, `height`, `borderRadius`) and the two match:
|
|
26
26
|
|
|
27
27
|
```html
|
|
28
28
|
<div id="paypal-button-container"></div>
|
|
@@ -138,12 +138,12 @@ await pybara.open({ amount: '25', frequency: 'monthly', durationMonths: 12 });
|
|
|
138
138
|
| Field | Type | Description |
|
|
139
139
|
|---|---|---|
|
|
140
140
|
| `createPayment()` | `function` | **Required.** Called on the click: the payment from the form, as `open()` takes it (`amount`, `currency`, `frequency`, donor fields), without callbacks. May return a promise |
|
|
141
|
-
| `style` | `{ color, shape, height }` | `color` `'brand'` \| `'black'` \| `'white'` (PayPal's names; its `'gold'`, `'blue'`, `'silver'` read as `'brand'`), `shape` `'pill'` \| `'rect'` \| `'sharp'`, `height` 25–55 px (default 45). Passed to the button as given |
|
|
141
|
+
| `style` | `{ color, shape, height, borderRadius }` | `color` `'brand'` \| `'black'` \| `'white'` (PayPal's names; its `'gold'`, `'blue'`, `'silver'` read as `'brand'`), `shape` `'pill'` \| `'rect'` \| `'sharp'`, `height` 25–55 px (default 45), `borderRadius` in px, overriding `shape` as PayPal's does. Passed to the button as given |
|
|
142
142
|
| `hideWhenUnavailable` | `boolean` | Collapse the button instead of leaving its slot empty when Pybara is unavailable |
|
|
143
143
|
| `onStateChange(availability)` | `function` | The checkout's availability answer, once per answer — see [Availability](#availability) |
|
|
144
144
|
| `onSuccess(result)` `onError(err)` `onClose()` | `function` | As `open()`'s |
|
|
145
145
|
|
|
146
|
-
`render(el)` takes an element or a selector, draws the button at the element's full width, and may be called again for another button; `destroy()` removes them all. Several `buttons()` calls share the one checkout.
|
|
146
|
+
`render(el)` takes an element or a selector, draws the button at the element's full width, and may be called again for another button; `destroy()` removes them all. Several `buttons()` calls share the one checkout. From the click until the checkout closes, the button shows "Processing…" in the checkout's `locale`, and takes no second click.
|
|
147
147
|
|
|
148
148
|
### Availability
|
|
149
149
|
|
|
@@ -189,7 +189,7 @@ If you want the whole donation *form* — presets, amount selector, frequency pi
|
|
|
189
189
|
|
|
190
190
|
## Internal entry points
|
|
191
191
|
|
|
192
|
-
`@pybara/pybara-js/modal` and `@pybara/pybara-js/admin` are Pybara's own machinery for its plugins: not part of the public API, with no compatibility promise between versions. Integrate with `Pybara.checkout()`.
|
|
192
|
+
`@pybara/pybara-js/modal`, `@pybara/pybara-js/button` and `@pybara/pybara-js/admin` are Pybara's own machinery for its plugins: not part of the public API, with no compatibility promise between versions. Integrate with `Pybara.checkout()`.
|
|
193
193
|
|
|
194
194
|
## Links
|
|
195
195
|
|
package/checkout.schema.json
CHANGED
|
@@ -159,7 +159,8 @@
|
|
|
159
159
|
"properties": {
|
|
160
160
|
"color": { "type": "string", "description": "'brand' | 'black' | 'white' (PayPal's names; its 'gold', 'blue', 'silver' read as 'brand'). Default 'brand'." },
|
|
161
161
|
"shape": { "type": "string", "description": "'pill' | 'rect' | 'sharp'. Default 'pill'." },
|
|
162
|
-
"height": { "type": "number", "minimum": 25, "maximum": 55, "description": "CSS pixels, PayPal's range. Default 45." }
|
|
162
|
+
"height": { "type": "number", "minimum": 25, "maximum": 55, "description": "CSS pixels, PayPal's range. Default 45." },
|
|
163
|
+
"borderRadius": { "type": "number", "minimum": 0, "description": "CSS pixels, overriding shape's corners, as PayPal's style.borderRadius. Above half the height it draws a pill." }
|
|
163
164
|
}
|
|
164
165
|
},
|
|
165
166
|
"hideWhenUnavailable": { "type": "boolean", "description": "Collapse the button to no height when Pybara is unavailable here; by default its slot stays, empty." },
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Availability } from '../modal/modal';
|
|
2
|
+
import { ButtonsOptions, ButtonStyle, PaymentParams, PybaraButtons } from '../types';
|
|
3
|
+
/** What renderButton() needs: where the button is served, how it looks, the availability answers, and what its click does. */
|
|
4
|
+
export interface RenderButtonOptions {
|
|
5
|
+
/** The wallet the button and its checkout are served from (pybara.io, or staging). */
|
|
6
|
+
walletUrl: string;
|
|
7
|
+
style?: ButtonStyle;
|
|
8
|
+
hideWhenUnavailable?: boolean;
|
|
9
|
+
/** The page's language (BCP 47, e.g. 'fr' or 'fr_FR'), for "Processing…"; English when the wallet doesn't have it. */
|
|
10
|
+
locale?: string;
|
|
11
|
+
/** Subscribes to every availability answer, first with the latest one if there is one; returns the unsubscribe. */
|
|
12
|
+
subscribeAvailability: (listener: (availability: Availability) => void) => () => void;
|
|
13
|
+
/** The payer's click: open the checkout. The button shows "Processing…" until idle() is called, or until this throws or rejects, so handle errors inside it. */
|
|
14
|
+
onClick: () => void | Promise<void>;
|
|
15
|
+
/** Each availability answer, and `unavailable` when the button doesn't load in time. */
|
|
16
|
+
onStateChange?: (availability: Availability) => void;
|
|
17
|
+
}
|
|
18
|
+
/** What renderButton() returns. */
|
|
19
|
+
export interface RenderedButton {
|
|
20
|
+
/** The checkout the click opened has closed or failed: the button shows its mark again and takes clicks. */
|
|
21
|
+
idle(): void;
|
|
22
|
+
/** Remove the button, and stop listening for it. */
|
|
23
|
+
destroy(): void;
|
|
24
|
+
}
|
|
25
|
+
/** What buttons() needs from its checkout: the frame's origin, the page's language, open(), and the availability answers. */
|
|
26
|
+
export interface ButtonsHost {
|
|
27
|
+
walletUrl: string;
|
|
28
|
+
locale?: string;
|
|
29
|
+
/** Resolves true when the checkout is up, false when it opened nothing that will close (a terminal message instead, or one already open). */
|
|
30
|
+
open(payment: PaymentParams): Promise<boolean>;
|
|
31
|
+
subscribeAvailability(listener: (availability: Availability) => void): () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Draw one served Pybara button in the element (or the first element matching the selector), at the style's height and the element's full width.
|
|
35
|
+
* For callers that drive their own checkout, such as the plugins with their CheckoutModal; a page with Pybara.checkout() uses checkout.buttons().
|
|
36
|
+
*/
|
|
37
|
+
export declare function renderButton(container: string | HTMLElement, options: RenderButtonOptions): RenderedButton;
|
|
38
|
+
export declare function createButtons(host: ButtonsHost, options: ButtonsOptions): PybaraButtons;
|
|
39
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/button/button.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAe,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAEtH,8HAA8H;AAC9H,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sHAAsH;IACtH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mHAAmH;IACnH,qBAAqB,EAAE,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACtF,gKAAgK;IAChK,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,wFAAwF;IACxF,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,CAAC;CACtD;AAED,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,4GAA4G;IAC5G,IAAI,IAAI,IAAI,CAAC;IACb,oDAAoD;IACpD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,6HAA6H;AAC7H,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6IAA6I;IAC7I,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,qBAAqB,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACnF;AAqBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,cAAc,CAgF1G;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAoDvF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pybara/pybara-js/button
|
|
3
|
+
*
|
|
4
|
+
* The served Pybara button on its own, for a first-party consumer that drives its own checkout (pybara-for-woocommerce's express checkout, with its CheckoutModal): renderButton() draws it and hands its click to the caller.
|
|
5
|
+
* Its own subpath, so a bundle that only draws the button doesn't take the modal with it.
|
|
6
|
+
* Pages use checkout.buttons() on the package root, built on the same renderButton().
|
|
7
|
+
*
|
|
8
|
+
* @internal Not part of the public API: no compatibility promise between versions, even minor ones.
|
|
9
|
+
*/
|
|
10
|
+
export { renderButton, type RenderButtonOptions, type RenderedButton } from './button.js';
|
|
11
|
+
export { type ButtonStyle } from '../types.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { n as renderButton } from "../button-BEOTKYpw.js";
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* Pybara.js - pybara.com */
|
|
2
|
+
import { t as e } from "./config-9RX2E1N4.js";
|
|
3
|
+
//#region src/types.ts
|
|
4
|
+
var t = class extends Error {
|
|
5
|
+
constructor(e, t) {
|
|
6
|
+
super(t), this.name = "PybaraError", this.code = e;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/button/button.ts
|
|
11
|
+
function n(e) {
|
|
12
|
+
let t = typeof e?.height == "number" && Number.isFinite(e.height) ? Math.round(e.height) : 45;
|
|
13
|
+
return Math.min(55, Math.max(25, t));
|
|
14
|
+
}
|
|
15
|
+
function r(e, t) {
|
|
16
|
+
return typeof e?.borderRadius == "number" && Number.isFinite(e.borderRadius) && e.borderRadius >= 0 ? `${e.borderRadius}px` : e?.shape === "sharp" ? "0" : e?.shape === "rect" ? "4px" : `${t / 2}px`;
|
|
17
|
+
}
|
|
18
|
+
function i(e) {
|
|
19
|
+
let n = typeof e == "string" ? document.querySelector(e) : e;
|
|
20
|
+
if (!n) throw new t("INVALID_CONFIG", `render(): no element matches ${JSON.stringify(e)}`);
|
|
21
|
+
return n;
|
|
22
|
+
}
|
|
23
|
+
function a(t, a) {
|
|
24
|
+
let o = i(t), s = new URL(a.walletUrl).origin, c = n(a.style), l = document.createElement("div");
|
|
25
|
+
l.style.cssText = `position:relative;width:100%;height:${c}px;`;
|
|
26
|
+
let u = document.createElement("div");
|
|
27
|
+
u.setAttribute("aria-hidden", "true"), u.style.cssText = `position:absolute;inset:0;border-radius:${r(a.style, c)};background:rgba(128,128,128,0.16);`;
|
|
28
|
+
let d = document.createElement("iframe");
|
|
29
|
+
d.src = `${s}/button`, d.title = "Pybara", d.style.cssText = "position:absolute;inset:0;width:100%;height:100%;border:0;opacity:0;color-scheme:normal;background:transparent;", l.append(u, d), o.appendChild(l);
|
|
30
|
+
let f = !1, p = null, m = (e) => {
|
|
31
|
+
d.contentWindow?.postMessage(e, s);
|
|
32
|
+
}, h = () => m({
|
|
33
|
+
type: "pybara_button_idle",
|
|
34
|
+
v: 1
|
|
35
|
+
}), g = (e) => {
|
|
36
|
+
p = e, f && m({
|
|
37
|
+
type: "pybara_button_availability",
|
|
38
|
+
v: 1,
|
|
39
|
+
status: e.status
|
|
40
|
+
}), a.onStateChange?.(e);
|
|
41
|
+
}, _ = setTimeout(() => {
|
|
42
|
+
if (f) return;
|
|
43
|
+
u.remove(), a.hideWhenUnavailable === !0 && (l.style.height = "0px");
|
|
44
|
+
let t = `Pybara: the button (${s}/button) did not load within ${e / 1e3} seconds; pybara.io may be unreachable from this browser.`;
|
|
45
|
+
console.warn(t), a.onStateChange?.({
|
|
46
|
+
status: "unavailable",
|
|
47
|
+
reason: "BUTTON_UNAVAILABLE",
|
|
48
|
+
detail: t
|
|
49
|
+
});
|
|
50
|
+
}, e);
|
|
51
|
+
d.addEventListener("load", () => {
|
|
52
|
+
m({
|
|
53
|
+
type: "pybara_button_init",
|
|
54
|
+
v: 1,
|
|
55
|
+
style: a.style ?? {},
|
|
56
|
+
hideWhenUnavailable: a.hideWhenUnavailable === !0,
|
|
57
|
+
locale: a.locale,
|
|
58
|
+
busy: !0
|
|
59
|
+
});
|
|
60
|
+
}, { once: !0 });
|
|
61
|
+
let v = (e) => {
|
|
62
|
+
if (e.origin !== s || e.source !== d.contentWindow) return;
|
|
63
|
+
let t = e.data;
|
|
64
|
+
t?.type === "pybara_button_ready" || t?.type === "pybara_button_resize" ? (typeof t.height == "number" && (l.style.height = `${t.height}px`), f || (f = !0, clearTimeout(_), d.style.opacity = "1", u.remove(), p && m({
|
|
65
|
+
type: "pybara_button_availability",
|
|
66
|
+
v: 1,
|
|
67
|
+
status: p.status
|
|
68
|
+
}))) : t?.type === "pybara_button_click" && (async () => {
|
|
69
|
+
try {
|
|
70
|
+
await a.onClick();
|
|
71
|
+
} catch {
|
|
72
|
+
h();
|
|
73
|
+
}
|
|
74
|
+
})();
|
|
75
|
+
};
|
|
76
|
+
window.addEventListener("message", v);
|
|
77
|
+
let y = a.subscribeAvailability(g);
|
|
78
|
+
return {
|
|
79
|
+
idle: h,
|
|
80
|
+
destroy() {
|
|
81
|
+
clearTimeout(_), window.removeEventListener("message", v), y(), l.remove();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function o(e, n) {
|
|
86
|
+
if (typeof n?.createPayment != "function") throw new t("INVALID_CONFIG", "buttons(): \"createPayment\" is required, a function returning the payment from the form, e.g. () => ({ amount: form.amount.value, currency: \"EUR\" })");
|
|
87
|
+
let r = [], i = () => {
|
|
88
|
+
for (let e of r) e.idle();
|
|
89
|
+
};
|
|
90
|
+
async function o() {
|
|
91
|
+
try {
|
|
92
|
+
let t = await n.createPayment();
|
|
93
|
+
await e.open({
|
|
94
|
+
...t,
|
|
95
|
+
onSuccess: n.onSuccess,
|
|
96
|
+
onError: (e) => {
|
|
97
|
+
i(), n.onError?.(e);
|
|
98
|
+
},
|
|
99
|
+
onClose: () => {
|
|
100
|
+
i(), n.onClose?.();
|
|
101
|
+
}
|
|
102
|
+
}) || i();
|
|
103
|
+
} catch (e) {
|
|
104
|
+
i(), n.onError?.(e instanceof Error ? e : Error(String(e)));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function s(t) {
|
|
108
|
+
let i = r.length === 0;
|
|
109
|
+
r.push(a(t, {
|
|
110
|
+
walletUrl: e.walletUrl,
|
|
111
|
+
style: n.style,
|
|
112
|
+
hideWhenUnavailable: n.hideWhenUnavailable,
|
|
113
|
+
locale: e.locale,
|
|
114
|
+
subscribeAvailability: e.subscribeAvailability,
|
|
115
|
+
onClick: o,
|
|
116
|
+
onStateChange: i ? n.onStateChange : void 0
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
render: s,
|
|
121
|
+
destroy() {
|
|
122
|
+
for (let e of r.splice(0)) e.destroy();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { a as n, t as r, o as t };
|
package/dist/checkout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAMA,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EAEnB,KAAK,aAAa,EAElB,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AAcjB;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,gIAAgI;IAChI,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAA8B;IACnD,uGAAuG;IACvG,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,8FAA8F;IAC9F,OAAO,CAAC,YAAY,CAA8C;IAClE,sGAAsG;IACtG,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAmD;IACzF,gEAAgE;IAChE,OAAO,CAAC,kBAAkB,CAA6B;gBAE3C,UAAU,EAAE,cAAc;IAQtC;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa;
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAMA,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EAEnB,KAAK,aAAa,EAElB,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AAcjB;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,gIAAgI;IAChI,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAA8B;IACnD,uGAAuG;IACvG,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,8FAA8F;IAC9F,OAAO,CAAC,YAAY,CAA8C;IAClE,sGAAsG;IACtG,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAmD;IACzF,gEAAgE;IAChE,OAAO,CAAC,kBAAkB,CAA6B;gBAE3C,UAAU,EAAE,cAAc;IAQtC;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa;IAqB/C,OAAO,CAAC,gBAAgB;IAKxB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;YAM9D,YAAY;IAkB1B,2IAA2I;IAC3I,IAAI,IAAI,IAAI,UAAU,GAAG,IAAI,CAE5B;IAED;;;;;OAKG;IACG,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EjD,4EAA4E;IAC5E,KAAK,IAAI,IAAI;YAIC,IAAI;IA8ClB,OAAO,CAAC,iBAAiB;IAyDzB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAmCnB,6FAA6F;IAC7F,OAAO,CAAC,gBAAgB;CAOzB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* Pybara.js - pybara.com */
|
|
2
|
+
//#region src/modal/config.ts
|
|
3
|
+
var e = {
|
|
4
|
+
Z_INDEX: 999999,
|
|
5
|
+
BACKGROUND: "rgba(0, 0, 0, 0.7)"
|
|
6
|
+
}, t = {
|
|
7
|
+
OVERLAY_FADE_IN_MS: 200,
|
|
8
|
+
PANEL_OPEN_MS: 300,
|
|
9
|
+
PANEL_CLOSE_MS: 200,
|
|
10
|
+
OVERLAY_FADE_OUT_DELAY_MS: 50,
|
|
11
|
+
OVERLAY_FADE_OUT_MS: 150,
|
|
12
|
+
RESIZE_MS: 600,
|
|
13
|
+
RESIZE_EASING: ""
|
|
14
|
+
}, n = 15e3;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { t as n, e as r, n as t };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export declare const Pybara: {
|
|
|
11
11
|
export { PybaraCheckout } from './checkout';
|
|
12
12
|
export { type Availability } from './modal/modal';
|
|
13
13
|
export { type WidgetGate } from './gate';
|
|
14
|
-
export { type ButtonPayment, type ButtonsOptions, type CheckoutConfig, type CheckoutResult, type Frequency, type PaymentParams, PybaraError, type PybaraButtons, type PybaraErrorCode, } from './types';
|
|
14
|
+
export { type ButtonPayment, type ButtonsOptions, type ButtonStyle, type CheckoutConfig, type CheckoutResult, type Frequency, type PaymentParams, PybaraError, type PybaraButtons, type PybaraErrorCode, } from './types';
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAE/D;AAID,eAAO,MAAM,MAAM;;CAAe,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAE/D;AAID,eAAO,MAAM,MAAM;;CAAe,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC"}
|
package/dist/modal/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as CheckoutModal, n as EmbeddedError } from "../modal-
|
|
1
|
+
export { t as CheckoutModal, n as EmbeddedError } from "../modal-CXTyI_BA.js";
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
/* Pybara.js - pybara.com */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
BACKGROUND: "rgba(0, 0, 0, 0.7)"
|
|
6
|
-
}, t = {
|
|
7
|
-
OVERLAY_FADE_IN_MS: 200,
|
|
8
|
-
PANEL_OPEN_MS: 300,
|
|
9
|
-
PANEL_CLOSE_MS: 200,
|
|
10
|
-
OVERLAY_FADE_OUT_DELAY_MS: 50,
|
|
11
|
-
OVERLAY_FADE_OUT_MS: 150,
|
|
12
|
-
RESIZE_MS: 600,
|
|
13
|
-
RESIZE_EASING: ""
|
|
14
|
-
}, n = 15e3, r = 0, i = 0, a = 0;
|
|
2
|
+
import { n as e, r as t, t as n } from "./config-9RX2E1N4.js";
|
|
3
|
+
//#region src/modal/lock-page-scroll.ts
|
|
4
|
+
var r = 0, i = 0, a = 0;
|
|
15
5
|
function o(e) {
|
|
16
6
|
e.preventDefault();
|
|
17
7
|
}
|
|
@@ -74,8 +64,8 @@ var _ = class {
|
|
|
74
64
|
left: 0;
|
|
75
65
|
right: 0;
|
|
76
66
|
bottom: 0;
|
|
77
|
-
background: ${
|
|
78
|
-
z-index: ${
|
|
67
|
+
background: ${t.BACKGROUND};
|
|
68
|
+
z-index: ${t.Z_INDEX};
|
|
79
69
|
display: none;
|
|
80
70
|
align-items: center;
|
|
81
71
|
justify-content: center;
|
|
@@ -88,39 +78,39 @@ var _ = class {
|
|
|
88
78
|
i.setAttribute("aria-hidden", "true"), i.style.cssText = "\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n ", i.innerHTML = "\n <svg viewBox=\"0 0 50 50\" width=\"50\" height=\"50\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"white\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"80\" stroke-dashoffset=\"20\"/>\n </svg>\n ", i.querySelector("svg")?.animate([{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }], {
|
|
89
79
|
duration: 1e3,
|
|
90
80
|
iterations: Infinity
|
|
91
|
-
}), r.addEventListener("load", () => this.onIframeLoad(), { once: !0 }), this.handleMessage = (
|
|
92
|
-
if (
|
|
81
|
+
}), r.addEventListener("load", () => this.onIframeLoad(), { once: !0 }), this.handleMessage = (t) => {
|
|
82
|
+
if (t.origin === this.walletOrigin && t.source === r.contentWindow && g(t.data)) switch (t.data.type) {
|
|
93
83
|
case "pybara_embedded_result":
|
|
94
84
|
this.config.onSuccess?.({
|
|
95
|
-
blockIndex:
|
|
96
|
-
reference:
|
|
97
|
-
payerPrincipal:
|
|
98
|
-
token:
|
|
85
|
+
blockIndex: t.data.blockIndex,
|
|
86
|
+
reference: t.data.reference,
|
|
87
|
+
payerPrincipal: t.data.payerPrincipal,
|
|
88
|
+
token: t.data.token
|
|
99
89
|
});
|
|
100
90
|
break;
|
|
101
91
|
case "pybara_embedded_error":
|
|
102
|
-
this.close(), this.config.onError?.(new h(m(
|
|
92
|
+
this.close(), this.config.onError?.(new h(m(t.data.code), t.data.message));
|
|
103
93
|
break;
|
|
104
94
|
case "pybara_embedded_closed":
|
|
105
95
|
this.close(), this.config.onClose?.();
|
|
106
96
|
break;
|
|
107
97
|
case "pybara_embedded_resize":
|
|
108
|
-
this.clearLoadTimer(), this.unavailableBox &&= (this.unavailableBox.remove(), null), r.style.height !== `${
|
|
98
|
+
this.clearLoadTimer(), this.unavailableBox &&= (this.unavailableBox.remove(), null), r.style.height !== `${t.data.height}px` && (r.style.height = `${t.data.height}px`), this.spinner && (this.spinner.remove(), this.spinner = null, f() || (r.animate([{
|
|
109
99
|
transform: "translateY(20px)",
|
|
110
100
|
opacity: 0
|
|
111
101
|
}, {
|
|
112
102
|
transform: "none",
|
|
113
103
|
opacity: 1
|
|
114
104
|
}], {
|
|
115
|
-
duration:
|
|
105
|
+
duration: e.PANEL_OPEN_MS,
|
|
116
106
|
easing: "ease"
|
|
117
|
-
}), r.offsetHeight, r.style.transition = `height ${
|
|
107
|
+
}), r.offsetHeight, r.style.transition = `height ${e.RESIZE_MS}ms ${e.RESIZE_EASING}`));
|
|
118
108
|
break;
|
|
119
109
|
case "pybara_embedded_closable":
|
|
120
|
-
this.closable =
|
|
110
|
+
this.closable = t.data.closable;
|
|
121
111
|
break;
|
|
122
112
|
case "pybara_embedded_availability": {
|
|
123
|
-
let { type:
|
|
113
|
+
let { type: e, v: n, ...r } = t.data;
|
|
124
114
|
r.status !== "available" && r.detail && console.warn(r.detail), this.config.onAvailability?.(r);
|
|
125
115
|
break;
|
|
126
116
|
}
|
|
@@ -186,14 +176,14 @@ var _ = class {
|
|
|
186
176
|
}
|
|
187
177
|
open() {
|
|
188
178
|
this.overlay && this.overlay.style.display !== "flex" && (u(), this.overlay.style.display = "flex", f() || this.overlay.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
189
|
-
duration:
|
|
179
|
+
duration: e.OVERLAY_FADE_IN_MS,
|
|
190
180
|
easing: "ease"
|
|
191
181
|
}));
|
|
192
182
|
}
|
|
193
183
|
show(e) {
|
|
194
184
|
this.open(), this.lastPaymentData = e, this.startLoadTimer(), this.iframeLoaded ? this.sendInitMessage(e) : this.pendingPaymentData = e;
|
|
195
185
|
}
|
|
196
|
-
renderTerminalState(
|
|
186
|
+
renderTerminalState(e) {
|
|
197
187
|
this.close(), u();
|
|
198
188
|
let n = document.createElement("div");
|
|
199
189
|
n.className = "pybara-checkout-overlay", n.style.cssText = `
|
|
@@ -202,38 +192,38 @@ var _ = class {
|
|
|
202
192
|
left: 0;
|
|
203
193
|
right: 0;
|
|
204
194
|
bottom: 0;
|
|
205
|
-
background: ${
|
|
206
|
-
z-index: ${
|
|
195
|
+
background: ${t.BACKGROUND};
|
|
196
|
+
z-index: ${t.Z_INDEX};
|
|
207
197
|
display: flex;
|
|
208
198
|
align-items: center;
|
|
209
199
|
justify-content: center;
|
|
210
200
|
user-select: none;
|
|
211
201
|
`;
|
|
212
202
|
let r = document.createElement("div");
|
|
213
|
-
r.style.cssText = "\n background: #fff;\n border-radius: 12px;\n color: #666;\n padding: 2rem;\n line-height: 1.4;\n max-width: 360px;\n text-align: center;\n font-family: system-ui, sans-serif;\n user-select: text;\n ", r.textContent =
|
|
203
|
+
r.style.cssText = "\n background: #fff;\n border-radius: 12px;\n color: #666;\n padding: 2rem;\n line-height: 1.4;\n max-width: 360px;\n text-align: center;\n font-family: system-ui, sans-serif;\n user-select: text;\n ", r.textContent = e, n.appendChild(r), n.addEventListener("click", (e) => {
|
|
214
204
|
e.target === n && (n.remove(), d(), this.config.onClose?.());
|
|
215
205
|
}), document.body.appendChild(n), this.overlay = n;
|
|
216
206
|
}
|
|
217
207
|
close() {
|
|
218
208
|
this.handleMessage &&= (window.removeEventListener("message", this.handleMessage), null), this.handleEscapeKey &&= (document.removeEventListener("keydown", this.handleEscapeKey), null), d();
|
|
219
|
-
let
|
|
220
|
-
this.overlay = null, this.iframe = null, this.spinner = null, this.iframeLoaded = !1, this.pendingPaymentData = null, this.lastPaymentData = null, this.pendingPrecheck = null, this.closable = !0, this.clearLoadTimer(), this.unavailableBox = null,
|
|
209
|
+
let t = this.overlay, n = this.iframe;
|
|
210
|
+
this.overlay = null, this.iframe = null, this.spinner = null, this.iframeLoaded = !1, this.pendingPaymentData = null, this.lastPaymentData = null, this.pendingPrecheck = null, this.closable = !0, this.clearLoadTimer(), this.unavailableBox = null, t && (t.style.display === "none" || f() ? t.remove() : (t.style.pointerEvents = "none", n?.animate([{
|
|
221
211
|
transform: "scale(1)",
|
|
222
212
|
opacity: 1
|
|
223
213
|
}, {
|
|
224
214
|
transform: "scale(0.95)",
|
|
225
215
|
opacity: 0
|
|
226
216
|
}], {
|
|
227
|
-
duration:
|
|
217
|
+
duration: e.PANEL_CLOSE_MS,
|
|
228
218
|
easing: "ease-out",
|
|
229
219
|
fill: "forwards"
|
|
230
|
-
}),
|
|
231
|
-
duration:
|
|
232
|
-
delay:
|
|
220
|
+
}), t.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
221
|
+
duration: e.OVERLAY_FADE_OUT_MS,
|
|
222
|
+
delay: e.OVERLAY_FADE_OUT_DELAY_MS,
|
|
233
223
|
easing: "ease-out",
|
|
234
224
|
fill: "forwards"
|
|
235
|
-
}).finished.then(() =>
|
|
225
|
+
}).finished.then(() => t.remove(), () => t.remove())));
|
|
236
226
|
}
|
|
237
227
|
};
|
|
238
228
|
//#endregion
|
|
239
|
-
export { h as n,
|
|
229
|
+
export { h as n, _ as t };
|
package/dist/pybara-js.iife.js
CHANGED
|
@@ -65,4 +65,4 @@ ic-request`);var ei=new TextEncoder().encode(`\vic-response`);new TextEncoder().
|
|
|
65
65
|
text-align: center;
|
|
66
66
|
font-family: system-ui, sans-serif;
|
|
67
67
|
user-select: text;
|
|
68
|
-
`,n.textContent=e,t.appendChild(n),t.addEventListener(`click`,e=>{e.target===t&&(t.remove(),Qu(),this.config.onClose?.())}),document.body.appendChild(t),this.overlay=t}close(){this.handleMessage&&=(window.removeEventListener(`message`,this.handleMessage),null),this.handleEscapeKey&&=(document.removeEventListener(`keydown`,this.handleEscapeKey),null),Qu();let e=this.overlay,t=this.iframe;this.overlay=null,this.iframe=null,this.spinner=null,this.iframeLoaded=!1,this.pendingPaymentData=null,this.lastPaymentData=null,this.pendingPrecheck=null,this.closable=!0,this.clearLoadTimer(),this.unavailableBox=null,e&&(e.style.display===`none`||$u()?e.remove():(e.style.pointerEvents=`none`,t?.animate([{transform:`scale(1)`,opacity:1},{transform:`scale(0.95)`,opacity:0}],{duration:Hu.PANEL_CLOSE_MS,easing:`ease-out`,fill:`forwards`}),e.animate([{opacity:1},{opacity:0}],{duration:Hu.OVERLAY_FADE_OUT_MS,delay:Hu.OVERLAY_FADE_OUT_DELAY_MS,easing:`ease-out`,fill:`forwards`}).finished.then(()=>e.remove(),()=>e.remove())))}},ad={widget:`donate-widget`,recurring:`donate-widget-recurring`};function od(e,t){let n=e=>{let t=/^(\d+)-(\d+)$/.exec(e);return t?[Number(t[1]),Number(t[2])]:null},r=n(e),i=n(t);return!r||!i?!1:r[0]>i[0]||r[0]===i[0]&&r[1]>=i[1]}async function sd(e){let t=await fetch(e);if(!t.ok)throw Error(`HTTP ${t.status} from ${e}`);return await t.json()}async function cd(e,t,n){let r=i[e],a=`https://${r.admin_core}.raw.icp0.io/widget-config`,o=`https://${r.admin_regs}.raw.icp0.io/widget-terms?site_url=${encodeURIComponent(t)}&principal=${encodeURIComponent(n)}`,s,c;try{[s,c]=await Promise.all([sd(a),sd(o)])}catch(e){return{show:!1,cause:`unreadable`,reason:`could not read the widget's configuration (${e instanceof Error?e.message:String(e)})`}}let l=s.kill_switch?.plugins??{};return l[ad.widget]?.enabled===!0?!c.signed||!c.version?{show:!1,cause:`terms`,reason:`${t} has not accepted the widget's terms in Pybara Wallet (Manage › Sites › Add a site without a plugin)`}:od(c.version,`1-0`)?{show:!0,recurring:l[ad.recurring]?.enabled===!0}:{show:!1,cause:`terms`,reason:`this widget version requires terms 1-0, and ${t} accepted ${c.version}: accept the new terms in Pybara Wallet (Manage › Sites)`}:{show:!1,cause:`switched-off`,reason:`the widget is switched off by Pybara for now`}}var $=class extends Error{constructor(e,t){super(t),this.name=`PybaraError`,this.code=e}};function ld(e){let t=typeof e?.height==`number`&&Number.isFinite(e.height)?Math.round(e.height):45;return Math.min(55,Math.max(25,t))}function ud(e,t){return e?.shape===`sharp`?`0`:e?.shape===`rect`?`4px`:`${t/2}px`}function dd(e){let t=typeof e==`string`?document.querySelector(e):e;if(!t)throw new $(`INVALID_CONFIG`,`buttons().render(): no element matches ${JSON.stringify(e)}`);return t}function fd(e,t){if(typeof t?.createPayment!=`function`)throw new $(`INVALID_CONFIG`,`buttons(): "createPayment" is required, a function returning the payment from the form, e.g. () => ({ amount: form.amount.value, currency: "EUR" })`);let n=new URL(e.walletUrl).origin,r=[],i=null;async function a(){try{let n=await t.createPayment();await e.open({...n,onSuccess:t.onSuccess,onError:t.onError,onClose:t.onClose})}catch(e){t.onError?.(e instanceof Error?e:Error(String(e)))}}function o(o){let s=dd(o),c=ld(t.style),l=document.createElement(`div`);l.style.cssText=`position:relative;width:100%;height:${c}px;`;let u=document.createElement(`div`);u.setAttribute(`aria-hidden`,`true`),u.style.cssText=`position:absolute;inset:0;border-radius:${ud(t.style,c)};background:rgba(128,128,128,0.16);`;let d=document.createElement(`iframe`);d.src=`${n}/button`,d.title=`Pybara`,d.style.cssText=`position:absolute;inset:0;width:100%;height:100%;border:0;opacity:0;color-scheme:normal;background:transparent;`,l.append(u,d),s.appendChild(l);let f=!1,p=null,m={};i??=m;let h=e=>{d.contentWindow?.postMessage(e,n)},g=e=>{p=e,f&&h({type:`pybara_button_availability`,v:1,status:e.status}),i??=m,i===m&&t.onStateChange?.(e)},_=setTimeout(()=>{if(f)return;u.remove(),t.hideWhenUnavailable===!0&&(l.style.height=`0px`);let e=`Pybara: the button (${n}/button) did not load within ${Uu/1e3} seconds; pybara.io may be unreachable from this browser.`;console.warn(e),i??=m,i===m&&t.onStateChange?.({status:`unavailable`,reason:`BUTTON_UNAVAILABLE`,detail:e})},Uu);d.addEventListener(`load`,()=>{h({type:`pybara_button_init`,v:1,style:t.style??{},hideWhenUnavailable:t.hideWhenUnavailable===!0})},{once:!0});let v=e=>{if(e.origin!==n||e.source!==d.contentWindow)return;let t=e.data;t?.type===`pybara_button_ready`||t?.type===`pybara_button_resize`?(typeof t.height==`number`&&(l.style.height=`${t.height}px`),f||(f=!0,clearTimeout(_),d.style.opacity=`1`,u.remove(),p&&h({type:`pybara_button_availability`,v:1,status:p.status}))):t?.type===`pybara_button_click`&&a()};window.addEventListener(`message`,v);let y=e.subscribeAvailability(g);r.push(()=>{clearTimeout(_),window.removeEventListener(`message`,v),y(),i===m&&(i=null),l.remove()})}return{render:o,destroy(){for(let e of r.splice(0))e()}}}var pd=/^(0|[1-9]\d*)(\.\d+)?$/,md=/^[a-z0-9-]{1,64}$/,hd=class{constructor(e){this.adminClient=null,this.modal=null,this.gateOutcome=null,this.isOpen=!1,this.completedPayment=!1,this.activePayment=null,this.lastPrecheck={},this.availabilityListeners=new Set,this.latestAvailability=null,this.config=vd(e),this.config.onAvailability&&this.availabilityListeners.add(this.config.onAvailability),this.ready=this.init(),this.config.onAvailability&&this.precheck()}buttons(e){return fd({walletUrl:r[this.config.staging?`staging`:`prod`],open:e=>this.open(e),subscribeAvailability:e=>(this.availabilityListeners.add(e),this.latestAvailability?e(this.latestAvailability):!this.config.onAvailability&&this.availabilityListeners.size===1&&this.precheck(this.lastPrecheck),()=>{this.availabilityListeners.delete(e)})},e)}emitAvailability(e){this.latestAvailability=e;for(let t of this.availabilityListeners)t(e)}precheck(e={}){let t=typeof e.amount==`number`&&Number.isFinite(e.amount)?String(e.amount):e.amount;this.lastPrecheck={amount:typeof t==`string`?t:void 0,currency:e.currency??this.config.currency},this.sendPrecheck()}async sendPrecheck(){if(this.availabilityListeners.size===0)return;await this.ready;let e=this.gateOutcome;if(e&&!e.show){let t=e.cause===`unreadable`?{status:`retry-later`,reason:`GATE_UNREADABLE`,detail:`Pybara: ${e.reason}; the checkout tries again at the click.`}:e.cause===`switched-off`?{status:`unavailable`,reason:`SWITCHED_OFF`,detail:`Pybara: ${e.reason}.`}:{status:`unavailable`,reason:`SITE_NOT_READY`,detail:`Pybara: ${e.reason}; the site owner does this, not the page. https://docs.pybara.com/pybara-js/setup/`};t.detail&&console.warn(t.detail),this.emitAvailability(t)}else this.modal?.precheck({beneficiary:this.config.recipientPrincipal,siteUrl:this.config.siteUrl,...this.lastPrecheck})}get gate(){return this.gateOutcome}async open(e){if(await this.ready,this.gateOutcome&&!this.gateOutcome.show)throw new $(`GATE_REFUSED`,this.gateOutcome.reason??`This site cannot accept Pybara payments yet.`);let t=gd(e.amount);if(t===null)throw new $(`INVALID_CONFIG`,`open(): "amount" must be a decimal string in the currency's major units, e.g. "12.34", or a positive number — got ${JSON.stringify(e.amount)}`);let n=e.currency??this.config.currency;if(!n)throw new $(`INVALID_CONFIG`,`open(): "currency" is required — pass it to open(), or set it once in Pybara.checkout()`);if(!/^[A-Z]{3}$/.test(n))throw new $(`INVALID_CONFIG`,`open(): "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(n)}`);if(e.durationMonths!=null&&!e.frequency)throw new $(`INVALID_CONFIG`,`open(): "durationMonths" needs a "frequency"`);let r=e.frequency?{frequency:e.frequency,...e.durationMonths==null?{}:{durationMonths:e.durationMonths}}:void 0;if(r&&this.gateOutcome&&this.gateOutcome.show&&!this.gateOutcome.recurring)throw new $(`GATE_REFUSED`,`Recurring payments are temporarily unavailable.`);if(this.isOpen)return;this.isOpen=!0;let i=!1;try{await this.adminClient?.getRecipientDataWithCache(this.config.siteUrl)}catch(e){this.config.debug&&console.warn(`🧩 pybara-js: recipient access validation failed:`,e),i=!0}this.modal||this.initCheckoutModal();let a=this.modal;if(!a)throw this.isOpen=!1,new $(`CHECKOUT_FAILED`,`The checkout modal could not be initialised.`);if(i)this.isOpen=!1,a.renderTerminalState(`This recipient is currently unable to accept donations.`),this.initCheckoutModal();else{this.activePayment=e;try{a.show({modalData:{beneficiary:this.config.recipientPrincipal,salt:yd(),reference:this.config.siteName},recurring:r,checkout:this.checkoutFor(e,t,n)})}catch(e){throw this.isOpen=!1,this.activePayment=null,bd(e)}}}close(){this.modal?.close()}async init(){let e=this.config.staging?`staging`:`prod`,t=this.config.debug;t&&console.log(`🧩 pybara-js: initializing checkout…`),this.preconnectWallet(e),this.initCheckoutModal();let n=new Bu({adminCoreCanisterId:i[e].admin_core,debug:t});this.adminClient=n;let r=(async()=>{try{await n.init(),await n.getPybaraAdminConfig(),t&&console.log(`🧩 pybara-js: admin client ready`),n.getRecipientDataWithCache(this.config.siteUrl).catch(e=>{t&&console.warn(`🧩 pybara-js: recipient prewarm failed:`,e)})}catch(e){t&&console.error(`🧩 pybara-js: admin client init failed:`,e)}})(),a=(async()=>{this.config.pluginVersion||(this.gateOutcome=await cd(e,this.config.siteUrl,this.config.recipientPrincipal),!this.gateOutcome.show&&t&&console.warn(`🧩 pybara-js: gate refused —`,this.gateOutcome.reason))})();await Promise.all([r,a])}initCheckoutModal(){let e=this.config.staging?`staging`:`prod`,t=this.config,n=this;this.modal=new id({walletUrl:r[e],context:`donation`,thankYouMessage:t.thankYouMessage,locale:t.locale,onAvailability:e=>n.emitAvailability(e),onSuccess:e=>{n.completedPayment=!0;let r=n.activePayment,i=r?.frequency!=null,a={blockIndex:e.blockIndex,reference:e.reference,token:e.token,recurring:i,frequency:r?.frequency,durationMonths:i?r?.durationMonths??void 0:void 0,isUnlimited:i&&r?.durationMonths==null,payerPrincipal:e.payerPrincipal,recipientPrincipal:t.recipientPrincipal};r?.onSuccess?.(a)},onError:e=>{n.isOpen=!1;let t=n.activePayment;n.activePayment=null,t?.onError?.(bd(e)),n.modal=null,n.initCheckoutModal()},onClose:()=>{n.isOpen=!1;let e=n.activePayment;n.activePayment=null,e?.onClose?.(),n.completedPayment&&t.thankYouRedirectUrl?window.location.href=t.thankYouRedirectUrl:(n.completedPayment=!1,n.modal=null,n.initCheckoutModal())}}),this.availabilityListeners.size>0&&this.modal&&Object.keys(this.lastPrecheck).length>0&&this.sendPrecheck()}checkoutFor(e,t,n){let r=this.config;return{v:1,amount:t,currency:n,site:{url:r.siteUrl,name:r.siteName,country:r.siteCountry},platform:r.platform??`pybara-js`,pluginVersion:r.pluginVersion,siteTerms:{version:r.recipientTosVersion,acceptedAt:r.recipientTosAcceptedAt},notify:{email:r.notifyEmail,enabled:r.notifyDonations},donation:{donor:{email:e.donorEmail,firstName:e.donorFirstName,lastName:e.donorLastName,company:e.donorCompany,country:e.donorCountry,address:{line1:e.donorAddressLine1,line2:e.donorAddressLine2,city:e.donorAddressCity,state:e.donorAddressState,postalCode:e.donorAddressPostalCode,country:e.donorAddressCountry},tos:{version:e.donorTosVersion,acceptedAt:e.donorTosAcceptedAt}},message:e.donorMessage,isAnonymous:e.donorIsAnonymous,wantsTaxReceipt:e.wantsTaxReceipt}}}preconnectWallet(e){let t=document.createElement(`link`);t.rel=`preconnect`,t.href=new URL(r[e]).origin,t.crossOrigin=`anonymous`,document.head.appendChild(t)}};function gd(e){let t=typeof e==`number`&&Number.isFinite(e)?String(e):e;return typeof t!=`string`||!pd.test(t)||!/[1-9]/.test(t)?null:t}function _d(e){let t=e.trim();if(!t)return null;let n;try{n=new URL(t.includes(`://`)?t:`https://${t}`)}catch{return null}return n.protocol!==`https:`&&n.protocol!==`http:`?null:n.origin+n.pathname.replace(/\/+$/,``)}function vd(e){if(!e.recipientPrincipal)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "recipientPrincipal" is required`);if(!e.siteUrl)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteUrl" is required`);let t=_d(e.siteUrl);if(!t)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteUrl" is not a valid http(s) URL: ${e.siteUrl}`);if(!e.siteName)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteName" is required`);if(e.currency!=null&&!/^[A-Z]{3}$/.test(e.currency))throw new $(`INVALID_CONFIG`,`Pybara.checkout: "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(e.currency)}`);if(e.platform!=null&&!md.test(e.platform))throw new $(`INVALID_CONFIG`,`Pybara.checkout: "platform" must be a lowercase slug (a-z, 0-9, -), at most 64 characters`);return{...e,siteUrl:t,staging:e.staging??!1,debug:e.debug??!1}}function yd(){let e=crypto.getRandomValues(new Uint8Array(16));return btoa(String.fromCharCode(...e))}function bd(e){return e instanceof Error?e:Error(String(e))}function xd(e){return new hd(e)}return e.Pybara={checkout:xd},e.PybaraCheckout=hd,e.PybaraError=$,e.checkout=xd,e})({});
|
|
68
|
+
`,n.textContent=e,t.appendChild(n),t.addEventListener(`click`,e=>{e.target===t&&(t.remove(),Qu(),this.config.onClose?.())}),document.body.appendChild(t),this.overlay=t}close(){this.handleMessage&&=(window.removeEventListener(`message`,this.handleMessage),null),this.handleEscapeKey&&=(document.removeEventListener(`keydown`,this.handleEscapeKey),null),Qu();let e=this.overlay,t=this.iframe;this.overlay=null,this.iframe=null,this.spinner=null,this.iframeLoaded=!1,this.pendingPaymentData=null,this.lastPaymentData=null,this.pendingPrecheck=null,this.closable=!0,this.clearLoadTimer(),this.unavailableBox=null,e&&(e.style.display===`none`||$u()?e.remove():(e.style.pointerEvents=`none`,t?.animate([{transform:`scale(1)`,opacity:1},{transform:`scale(0.95)`,opacity:0}],{duration:Hu.PANEL_CLOSE_MS,easing:`ease-out`,fill:`forwards`}),e.animate([{opacity:1},{opacity:0}],{duration:Hu.OVERLAY_FADE_OUT_MS,delay:Hu.OVERLAY_FADE_OUT_DELAY_MS,easing:`ease-out`,fill:`forwards`}).finished.then(()=>e.remove(),()=>e.remove())))}},ad={widget:`donate-widget`,recurring:`donate-widget-recurring`};function od(e,t){let n=e=>{let t=/^(\d+)-(\d+)$/.exec(e);return t?[Number(t[1]),Number(t[2])]:null},r=n(e),i=n(t);return!r||!i?!1:r[0]>i[0]||r[0]===i[0]&&r[1]>=i[1]}async function sd(e){let t=await fetch(e);if(!t.ok)throw Error(`HTTP ${t.status} from ${e}`);return await t.json()}async function cd(e,t,n){let r=i[e],a=`https://${r.admin_core}.raw.icp0.io/widget-config`,o=`https://${r.admin_regs}.raw.icp0.io/widget-terms?site_url=${encodeURIComponent(t)}&principal=${encodeURIComponent(n)}`,s,c;try{[s,c]=await Promise.all([sd(a),sd(o)])}catch(e){return{show:!1,cause:`unreadable`,reason:`could not read the widget's configuration (${e instanceof Error?e.message:String(e)})`}}let l=s.kill_switch?.plugins??{};return l[ad.widget]?.enabled===!0?!c.signed||!c.version?{show:!1,cause:`terms`,reason:`${t} has not accepted the widget's terms in Pybara Wallet (Manage › Sites › Add a site without a plugin)`}:od(c.version,`1-0`)?{show:!0,recurring:l[ad.recurring]?.enabled===!0}:{show:!1,cause:`terms`,reason:`this widget version requires terms 1-0, and ${t} accepted ${c.version}: accept the new terms in Pybara Wallet (Manage › Sites)`}:{show:!1,cause:`switched-off`,reason:`the widget is switched off by Pybara for now`}}var $=class extends Error{constructor(e,t){super(t),this.name=`PybaraError`,this.code=e}};function ld(e){let t=typeof e?.height==`number`&&Number.isFinite(e.height)?Math.round(e.height):45;return Math.min(55,Math.max(25,t))}function ud(e,t){return typeof e?.borderRadius==`number`&&Number.isFinite(e.borderRadius)&&e.borderRadius>=0?`${e.borderRadius}px`:e?.shape===`sharp`?`0`:e?.shape===`rect`?`4px`:`${t/2}px`}function dd(e){let t=typeof e==`string`?document.querySelector(e):e;if(!t)throw new $(`INVALID_CONFIG`,`render(): no element matches ${JSON.stringify(e)}`);return t}function fd(e,t){let n=dd(e),r=new URL(t.walletUrl).origin,i=ld(t.style),a=document.createElement(`div`);a.style.cssText=`position:relative;width:100%;height:${i}px;`;let o=document.createElement(`div`);o.setAttribute(`aria-hidden`,`true`),o.style.cssText=`position:absolute;inset:0;border-radius:${ud(t.style,i)};background:rgba(128,128,128,0.16);`;let s=document.createElement(`iframe`);s.src=`${r}/button`,s.title=`Pybara`,s.style.cssText=`position:absolute;inset:0;width:100%;height:100%;border:0;opacity:0;color-scheme:normal;background:transparent;`,a.append(o,s),n.appendChild(a);let c=!1,l=null,u=e=>{s.contentWindow?.postMessage(e,r)},d=()=>u({type:`pybara_button_idle`,v:1}),f=e=>{l=e,c&&u({type:`pybara_button_availability`,v:1,status:e.status}),t.onStateChange?.(e)},p=setTimeout(()=>{if(c)return;o.remove(),t.hideWhenUnavailable===!0&&(a.style.height=`0px`);let e=`Pybara: the button (${r}/button) did not load within ${Uu/1e3} seconds; pybara.io may be unreachable from this browser.`;console.warn(e),t.onStateChange?.({status:`unavailable`,reason:`BUTTON_UNAVAILABLE`,detail:e})},Uu);s.addEventListener(`load`,()=>{u({type:`pybara_button_init`,v:1,style:t.style??{},hideWhenUnavailable:t.hideWhenUnavailable===!0,locale:t.locale,busy:!0})},{once:!0});let m=e=>{if(e.origin!==r||e.source!==s.contentWindow)return;let n=e.data;n?.type===`pybara_button_ready`||n?.type===`pybara_button_resize`?(typeof n.height==`number`&&(a.style.height=`${n.height}px`),c||(c=!0,clearTimeout(p),s.style.opacity=`1`,o.remove(),l&&u({type:`pybara_button_availability`,v:1,status:l.status}))):n?.type===`pybara_button_click`&&(async()=>{try{await t.onClick()}catch{d()}})()};window.addEventListener(`message`,m);let h=t.subscribeAvailability(f);return{idle:d,destroy(){clearTimeout(p),window.removeEventListener(`message`,m),h(),a.remove()}}}function pd(e,t){if(typeof t?.createPayment!=`function`)throw new $(`INVALID_CONFIG`,`buttons(): "createPayment" is required, a function returning the payment from the form, e.g. () => ({ amount: form.amount.value, currency: "EUR" })`);let n=[],r=()=>{for(let e of n)e.idle()};async function i(){try{let n=await t.createPayment();await e.open({...n,onSuccess:t.onSuccess,onError:e=>{r(),t.onError?.(e)},onClose:()=>{r(),t.onClose?.()}})||r()}catch(e){r(),t.onError?.(e instanceof Error?e:Error(String(e)))}}function a(r){let a=n.length===0;n.push(fd(r,{walletUrl:e.walletUrl,style:t.style,hideWhenUnavailable:t.hideWhenUnavailable,locale:e.locale,subscribeAvailability:e.subscribeAvailability,onClick:i,onStateChange:a?t.onStateChange:void 0}))}return{render:a,destroy(){for(let e of n.splice(0))e.destroy()}}}var md=/^(0|[1-9]\d*)(\.\d+)?$/,hd=/^[a-z0-9-]{1,64}$/,gd=class{constructor(e){this.adminClient=null,this.modal=null,this.gateOutcome=null,this.isOpen=!1,this.completedPayment=!1,this.activePayment=null,this.lastPrecheck={},this.availabilityListeners=new Set,this.latestAvailability=null,this.config=yd(e),this.config.onAvailability&&this.availabilityListeners.add(this.config.onAvailability),this.ready=this.init(),this.config.onAvailability&&this.precheck()}buttons(e){return pd({walletUrl:r[this.config.staging?`staging`:`prod`],locale:this.config.locale,open:async e=>(await this.open(e),this.activePayment===e),subscribeAvailability:e=>(this.availabilityListeners.add(e),this.latestAvailability?e(this.latestAvailability):!this.config.onAvailability&&this.availabilityListeners.size===1&&this.precheck(this.lastPrecheck),()=>{this.availabilityListeners.delete(e)})},e)}emitAvailability(e){this.latestAvailability=e;for(let t of this.availabilityListeners)t(e)}precheck(e={}){let t=typeof e.amount==`number`&&Number.isFinite(e.amount)?String(e.amount):e.amount;this.lastPrecheck={amount:typeof t==`string`?t:void 0,currency:e.currency??this.config.currency},this.sendPrecheck()}async sendPrecheck(){if(this.availabilityListeners.size===0)return;await this.ready;let e=this.gateOutcome;if(e&&!e.show){let t=e.cause===`unreadable`?{status:`retry-later`,reason:`GATE_UNREADABLE`,detail:`Pybara: ${e.reason}; the checkout tries again at the click.`}:e.cause===`switched-off`?{status:`unavailable`,reason:`SWITCHED_OFF`,detail:`Pybara: ${e.reason}.`}:{status:`unavailable`,reason:`SITE_NOT_READY`,detail:`Pybara: ${e.reason}; the site owner does this, not the page. https://docs.pybara.com/pybara-js/setup/`};t.detail&&console.warn(t.detail),this.emitAvailability(t)}else this.modal?.precheck({beneficiary:this.config.recipientPrincipal,siteUrl:this.config.siteUrl,...this.lastPrecheck})}get gate(){return this.gateOutcome}async open(e){if(await this.ready,this.gateOutcome&&!this.gateOutcome.show)throw new $(`GATE_REFUSED`,this.gateOutcome.reason??`This site cannot accept Pybara payments yet.`);let t=_d(e.amount);if(t===null)throw new $(`INVALID_CONFIG`,`open(): "amount" must be a decimal string in the currency's major units, e.g. "12.34", or a positive number — got ${JSON.stringify(e.amount)}`);let n=e.currency??this.config.currency;if(!n)throw new $(`INVALID_CONFIG`,`open(): "currency" is required — pass it to open(), or set it once in Pybara.checkout()`);if(!/^[A-Z]{3}$/.test(n))throw new $(`INVALID_CONFIG`,`open(): "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(n)}`);if(e.durationMonths!=null&&!e.frequency)throw new $(`INVALID_CONFIG`,`open(): "durationMonths" needs a "frequency"`);let r=e.frequency?{frequency:e.frequency,...e.durationMonths==null?{}:{durationMonths:e.durationMonths}}:void 0;if(r&&this.gateOutcome&&this.gateOutcome.show&&!this.gateOutcome.recurring)throw new $(`GATE_REFUSED`,`Recurring payments are temporarily unavailable.`);if(this.isOpen)return;this.isOpen=!0;let i=!1;try{await this.adminClient?.getRecipientDataWithCache(this.config.siteUrl)}catch(e){this.config.debug&&console.warn(`🧩 pybara-js: recipient access validation failed:`,e),i=!0}this.modal||this.initCheckoutModal();let a=this.modal;if(!a)throw this.isOpen=!1,new $(`CHECKOUT_FAILED`,`The checkout modal could not be initialised.`);if(i)this.isOpen=!1,a.renderTerminalState(`This recipient is currently unable to accept donations.`),this.initCheckoutModal();else{this.activePayment=e;try{a.show({modalData:{beneficiary:this.config.recipientPrincipal,salt:bd(),reference:this.config.siteName},recurring:r,checkout:this.checkoutFor(e,t,n)})}catch(e){throw this.isOpen=!1,this.activePayment=null,xd(e)}}}close(){this.modal?.close()}async init(){let e=this.config.staging?`staging`:`prod`,t=this.config.debug;t&&console.log(`🧩 pybara-js: initializing checkout…`),this.preconnectWallet(e),this.initCheckoutModal();let n=new Bu({adminCoreCanisterId:i[e].admin_core,debug:t});this.adminClient=n;let r=(async()=>{try{await n.init(),await n.getPybaraAdminConfig(),t&&console.log(`🧩 pybara-js: admin client ready`),n.getRecipientDataWithCache(this.config.siteUrl).catch(e=>{t&&console.warn(`🧩 pybara-js: recipient prewarm failed:`,e)})}catch(e){t&&console.error(`🧩 pybara-js: admin client init failed:`,e)}})(),a=(async()=>{this.config.pluginVersion||(this.gateOutcome=await cd(e,this.config.siteUrl,this.config.recipientPrincipal),!this.gateOutcome.show&&t&&console.warn(`🧩 pybara-js: gate refused —`,this.gateOutcome.reason))})();await Promise.all([r,a])}initCheckoutModal(){let e=this.config.staging?`staging`:`prod`,t=this.config,n=this;this.modal=new id({walletUrl:r[e],context:`donation`,thankYouMessage:t.thankYouMessage,locale:t.locale,onAvailability:e=>n.emitAvailability(e),onSuccess:e=>{n.completedPayment=!0;let r=n.activePayment,i=r?.frequency!=null,a={blockIndex:e.blockIndex,reference:e.reference,token:e.token,recurring:i,frequency:r?.frequency,durationMonths:i?r?.durationMonths??void 0:void 0,isUnlimited:i&&r?.durationMonths==null,payerPrincipal:e.payerPrincipal,recipientPrincipal:t.recipientPrincipal};r?.onSuccess?.(a)},onError:e=>{n.isOpen=!1;let t=n.activePayment;n.activePayment=null,t?.onError?.(xd(e)),n.modal=null,n.initCheckoutModal()},onClose:()=>{n.isOpen=!1;let e=n.activePayment;n.activePayment=null,e?.onClose?.(),n.completedPayment&&t.thankYouRedirectUrl?window.location.href=t.thankYouRedirectUrl:(n.completedPayment=!1,n.modal=null,n.initCheckoutModal())}}),this.availabilityListeners.size>0&&this.modal&&Object.keys(this.lastPrecheck).length>0&&this.sendPrecheck()}checkoutFor(e,t,n){let r=this.config;return{v:1,amount:t,currency:n,site:{url:r.siteUrl,name:r.siteName,country:r.siteCountry},platform:r.platform??`pybara-js`,pluginVersion:r.pluginVersion,siteTerms:{version:r.recipientTosVersion,acceptedAt:r.recipientTosAcceptedAt},notify:{email:r.notifyEmail,enabled:r.notifyDonations},donation:{donor:{email:e.donorEmail,firstName:e.donorFirstName,lastName:e.donorLastName,company:e.donorCompany,country:e.donorCountry,address:{line1:e.donorAddressLine1,line2:e.donorAddressLine2,city:e.donorAddressCity,state:e.donorAddressState,postalCode:e.donorAddressPostalCode,country:e.donorAddressCountry},tos:{version:e.donorTosVersion,acceptedAt:e.donorTosAcceptedAt}},message:e.donorMessage,isAnonymous:e.donorIsAnonymous,wantsTaxReceipt:e.wantsTaxReceipt}}}preconnectWallet(e){let t=document.createElement(`link`);t.rel=`preconnect`,t.href=new URL(r[e]).origin,t.crossOrigin=`anonymous`,document.head.appendChild(t)}};function _d(e){let t=typeof e==`number`&&Number.isFinite(e)?String(e):e;return typeof t!=`string`||!md.test(t)||!/[1-9]/.test(t)?null:t}function vd(e){let t=e.trim();if(!t)return null;let n;try{n=new URL(t.includes(`://`)?t:`https://${t}`)}catch{return null}return n.protocol!==`https:`&&n.protocol!==`http:`?null:n.origin+n.pathname.replace(/\/+$/,``)}function yd(e){if(!e.recipientPrincipal)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "recipientPrincipal" is required`);if(!e.siteUrl)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteUrl" is required`);let t=vd(e.siteUrl);if(!t)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteUrl" is not a valid http(s) URL: ${e.siteUrl}`);if(!e.siteName)throw new $(`INVALID_CONFIG`,`Pybara.checkout: "siteName" is required`);if(e.currency!=null&&!/^[A-Z]{3}$/.test(e.currency))throw new $(`INVALID_CONFIG`,`Pybara.checkout: "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(e.currency)}`);if(e.platform!=null&&!hd.test(e.platform))throw new $(`INVALID_CONFIG`,`Pybara.checkout: "platform" must be a lowercase slug (a-z, 0-9, -), at most 64 characters`);return{...e,siteUrl:t,staging:e.staging??!1,debug:e.debug??!1}}function bd(){let e=crypto.getRandomValues(new Uint8Array(16));return btoa(String.fromCharCode(...e))}function xd(e){return e instanceof Error?e:Error(String(e))}function Sd(e){return new gd(e)}return e.Pybara={checkout:Sd},e.PybaraCheckout=gd,e.PybaraError=$,e.checkout=Sd,e})({});
|
package/dist/pybara-js.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
/* Pybara.js - pybara.com */
|
|
2
2
|
import { n as e, r as t, t as n } from "./admin-B1pVP25-.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { t as r } from "./modal-CXTyI_BA.js";
|
|
4
|
+
import { r as i, t as a } from "./button-BEOTKYpw.js";
|
|
5
|
+
var o = {
|
|
5
6
|
widget: "donate-widget",
|
|
6
7
|
recurring: "donate-widget-recurring"
|
|
7
8
|
};
|
|
8
|
-
function
|
|
9
|
+
function s(e, t) {
|
|
9
10
|
let n = (e) => {
|
|
10
11
|
let t = /^(\d+)-(\d+)$/.exec(e);
|
|
11
12
|
return t ? [Number(t[1]), Number(t[2])] : null;
|
|
12
13
|
}, r = n(e), i = n(t);
|
|
13
14
|
return !r || !i ? !1 : r[0] > i[0] || r[0] === i[0] && r[1] >= i[1];
|
|
14
15
|
}
|
|
15
|
-
async function
|
|
16
|
+
async function c(e) {
|
|
16
17
|
let t = await fetch(e);
|
|
17
18
|
if (!t.ok) throw Error(`HTTP ${t.status} from ${e}`);
|
|
18
19
|
return await t.json();
|
|
19
20
|
}
|
|
20
|
-
async function
|
|
21
|
-
let i = e[t],
|
|
21
|
+
async function l(t, n, r) {
|
|
22
|
+
let i = e[t], a = `https://${i.admin_core}.raw.icp0.io/widget-config`, l = `https://${i.admin_regs}.raw.icp0.io/widget-terms?site_url=${encodeURIComponent(n)}&principal=${encodeURIComponent(r)}`, u, d;
|
|
22
23
|
try {
|
|
23
|
-
[u, d] = await Promise.all([
|
|
24
|
+
[u, d] = await Promise.all([c(a), c(l)]);
|
|
24
25
|
} catch (e) {
|
|
25
26
|
return {
|
|
26
27
|
show: !1,
|
|
@@ -29,13 +30,13 @@ async function c(t, n, r) {
|
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
let f = u.kill_switch?.plugins ?? {};
|
|
32
|
-
return f[
|
|
33
|
+
return f[o.widget]?.enabled === !0 ? !d.signed || !d.version ? {
|
|
33
34
|
show: !1,
|
|
34
35
|
cause: "terms",
|
|
35
36
|
reason: `${n} has not accepted the widget's terms in Pybara Wallet (Manage › Sites › Add a site without a plugin)`
|
|
36
|
-
} :
|
|
37
|
+
} : s(d.version, "1-0") ? {
|
|
37
38
|
show: !0,
|
|
38
|
-
recurring: f[
|
|
39
|
+
recurring: f[o.recurring]?.enabled === !0
|
|
39
40
|
} : {
|
|
40
41
|
show: !1,
|
|
41
42
|
cause: "terms",
|
|
@@ -47,109 +48,16 @@ async function c(t, n, r) {
|
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
//#endregion
|
|
50
|
-
//#region src/types.ts
|
|
51
|
-
var l = class extends Error {
|
|
52
|
-
constructor(e, t) {
|
|
53
|
-
super(t), this.name = "PybaraError", this.code = e;
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
//#endregion
|
|
57
|
-
//#region src/buttons.ts
|
|
58
|
-
function u(e) {
|
|
59
|
-
let t = typeof e?.height == "number" && Number.isFinite(e.height) ? Math.round(e.height) : 45;
|
|
60
|
-
return Math.min(55, Math.max(25, t));
|
|
61
|
-
}
|
|
62
|
-
function d(e, t) {
|
|
63
|
-
return e?.shape === "sharp" ? "0" : e?.shape === "rect" ? "4px" : `${t / 2}px`;
|
|
64
|
-
}
|
|
65
|
-
function f(e) {
|
|
66
|
-
let t = typeof e == "string" ? document.querySelector(e) : e;
|
|
67
|
-
if (!t) throw new l("INVALID_CONFIG", `buttons().render(): no element matches ${JSON.stringify(e)}`);
|
|
68
|
-
return t;
|
|
69
|
-
}
|
|
70
|
-
function p(e, t) {
|
|
71
|
-
if (typeof t?.createPayment != "function") throw new l("INVALID_CONFIG", "buttons(): \"createPayment\" is required, a function returning the payment from the form, e.g. () => ({ amount: form.amount.value, currency: \"EUR\" })");
|
|
72
|
-
let n = new URL(e.walletUrl).origin, i = [], a = null;
|
|
73
|
-
async function o() {
|
|
74
|
-
try {
|
|
75
|
-
let n = await t.createPayment();
|
|
76
|
-
await e.open({
|
|
77
|
-
...n,
|
|
78
|
-
onSuccess: t.onSuccess,
|
|
79
|
-
onError: t.onError,
|
|
80
|
-
onClose: t.onClose
|
|
81
|
-
});
|
|
82
|
-
} catch (e) {
|
|
83
|
-
t.onError?.(e instanceof Error ? e : Error(String(e)));
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function s(s) {
|
|
87
|
-
let c = f(s), l = u(t.style), p = document.createElement("div");
|
|
88
|
-
p.style.cssText = `position:relative;width:100%;height:${l}px;`;
|
|
89
|
-
let m = document.createElement("div");
|
|
90
|
-
m.setAttribute("aria-hidden", "true"), m.style.cssText = `position:absolute;inset:0;border-radius:${d(t.style, l)};background:rgba(128,128,128,0.16);`;
|
|
91
|
-
let h = document.createElement("iframe");
|
|
92
|
-
h.src = `${n}/button`, h.title = "Pybara", h.style.cssText = "position:absolute;inset:0;width:100%;height:100%;border:0;opacity:0;color-scheme:normal;background:transparent;", p.append(m, h), c.appendChild(p);
|
|
93
|
-
let g = !1, _ = null, v = {};
|
|
94
|
-
a ??= v;
|
|
95
|
-
let y = (e) => {
|
|
96
|
-
h.contentWindow?.postMessage(e, n);
|
|
97
|
-
}, b = (e) => {
|
|
98
|
-
_ = e, g && y({
|
|
99
|
-
type: "pybara_button_availability",
|
|
100
|
-
v: 1,
|
|
101
|
-
status: e.status
|
|
102
|
-
}), a ??= v, a === v && t.onStateChange?.(e);
|
|
103
|
-
}, x = setTimeout(() => {
|
|
104
|
-
if (g) return;
|
|
105
|
-
m.remove(), t.hideWhenUnavailable === !0 && (p.style.height = "0px");
|
|
106
|
-
let e = `Pybara: the button (${n}/button) did not load within ${r / 1e3} seconds; pybara.io may be unreachable from this browser.`;
|
|
107
|
-
console.warn(e), a ??= v, a === v && t.onStateChange?.({
|
|
108
|
-
status: "unavailable",
|
|
109
|
-
reason: "BUTTON_UNAVAILABLE",
|
|
110
|
-
detail: e
|
|
111
|
-
});
|
|
112
|
-
}, r);
|
|
113
|
-
h.addEventListener("load", () => {
|
|
114
|
-
y({
|
|
115
|
-
type: "pybara_button_init",
|
|
116
|
-
v: 1,
|
|
117
|
-
style: t.style ?? {},
|
|
118
|
-
hideWhenUnavailable: t.hideWhenUnavailable === !0
|
|
119
|
-
});
|
|
120
|
-
}, { once: !0 });
|
|
121
|
-
let S = (e) => {
|
|
122
|
-
if (e.origin !== n || e.source !== h.contentWindow) return;
|
|
123
|
-
let t = e.data;
|
|
124
|
-
t?.type === "pybara_button_ready" || t?.type === "pybara_button_resize" ? (typeof t.height == "number" && (p.style.height = `${t.height}px`), g || (g = !0, clearTimeout(x), h.style.opacity = "1", m.remove(), _ && y({
|
|
125
|
-
type: "pybara_button_availability",
|
|
126
|
-
v: 1,
|
|
127
|
-
status: _.status
|
|
128
|
-
}))) : t?.type === "pybara_button_click" && o();
|
|
129
|
-
};
|
|
130
|
-
window.addEventListener("message", S);
|
|
131
|
-
let C = e.subscribeAvailability(b);
|
|
132
|
-
i.push(() => {
|
|
133
|
-
clearTimeout(x), window.removeEventListener("message", S), C(), a === v && (a = null), p.remove();
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return {
|
|
137
|
-
render: s,
|
|
138
|
-
destroy() {
|
|
139
|
-
for (let e of i.splice(0)) e();
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
//#endregion
|
|
144
51
|
//#region src/checkout.ts
|
|
145
|
-
var
|
|
52
|
+
var u = /^(0|[1-9]\d*)(\.\d+)?$/, d = /^[a-z0-9-]{1,64}$/, f = class {
|
|
146
53
|
constructor(e) {
|
|
147
|
-
this.adminClient = null, this.modal = null, this.gateOutcome = null, this.isOpen = !1, this.completedPayment = !1, this.activePayment = null, this.lastPrecheck = {}, this.availabilityListeners = /* @__PURE__ */ new Set(), this.latestAvailability = null, this.config =
|
|
54
|
+
this.adminClient = null, this.modal = null, this.gateOutcome = null, this.isOpen = !1, this.completedPayment = !1, this.activePayment = null, this.lastPrecheck = {}, this.availabilityListeners = /* @__PURE__ */ new Set(), this.latestAvailability = null, this.config = h(e), this.config.onAvailability && this.availabilityListeners.add(this.config.onAvailability), this.ready = this.init(), this.config.onAvailability && this.precheck();
|
|
148
55
|
}
|
|
149
56
|
buttons(e) {
|
|
150
|
-
return
|
|
57
|
+
return a({
|
|
151
58
|
walletUrl: t[this.config.staging ? "staging" : "prod"],
|
|
152
|
-
|
|
59
|
+
locale: this.config.locale,
|
|
60
|
+
open: async (e) => (await this.open(e), this.activePayment === e),
|
|
153
61
|
subscribeAvailability: (e) => (this.availabilityListeners.add(e), this.latestAvailability ? e(this.latestAvailability) : !this.config.onAvailability && this.availabilityListeners.size === 1 && this.precheck(this.lastPrecheck), () => {
|
|
154
62
|
this.availabilityListeners.delete(e);
|
|
155
63
|
})
|
|
@@ -195,44 +103,44 @@ var m = /^(0|[1-9]\d*)(\.\d+)?$/, h = /^[a-z0-9-]{1,64}$/, g = class {
|
|
|
195
103
|
return this.gateOutcome;
|
|
196
104
|
}
|
|
197
105
|
async open(e) {
|
|
198
|
-
if (await this.ready, this.gateOutcome && !this.gateOutcome.show) throw new
|
|
199
|
-
let t =
|
|
200
|
-
if (t === null) throw new
|
|
106
|
+
if (await this.ready, this.gateOutcome && !this.gateOutcome.show) throw new i("GATE_REFUSED", this.gateOutcome.reason ?? "This site cannot accept Pybara payments yet.");
|
|
107
|
+
let t = p(e.amount);
|
|
108
|
+
if (t === null) throw new i("INVALID_CONFIG", `open(): "amount" must be a decimal string in the currency's major units, e.g. "12.34", or a positive number — got ${JSON.stringify(e.amount)}`);
|
|
201
109
|
let n = e.currency ?? this.config.currency;
|
|
202
|
-
if (!n) throw new
|
|
203
|
-
if (!/^[A-Z]{3}$/.test(n)) throw new
|
|
204
|
-
if (e.durationMonths != null && !e.frequency) throw new
|
|
110
|
+
if (!n) throw new i("INVALID_CONFIG", "open(): \"currency\" is required — pass it to open(), or set it once in Pybara.checkout()");
|
|
111
|
+
if (!/^[A-Z]{3}$/.test(n)) throw new i("INVALID_CONFIG", `open(): "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(n)}`);
|
|
112
|
+
if (e.durationMonths != null && !e.frequency) throw new i("INVALID_CONFIG", "open(): \"durationMonths\" needs a \"frequency\"");
|
|
205
113
|
let r = e.frequency ? {
|
|
206
114
|
frequency: e.frequency,
|
|
207
115
|
...e.durationMonths == null ? {} : { durationMonths: e.durationMonths }
|
|
208
116
|
} : void 0;
|
|
209
|
-
if (r && this.gateOutcome && this.gateOutcome.show && !this.gateOutcome.recurring) throw new
|
|
117
|
+
if (r && this.gateOutcome && this.gateOutcome.show && !this.gateOutcome.recurring) throw new i("GATE_REFUSED", "Recurring payments are temporarily unavailable.");
|
|
210
118
|
if (this.isOpen) return;
|
|
211
119
|
this.isOpen = !0;
|
|
212
|
-
let
|
|
120
|
+
let a = !1;
|
|
213
121
|
try {
|
|
214
122
|
await this.adminClient?.getRecipientDataWithCache(this.config.siteUrl);
|
|
215
123
|
} catch (e) {
|
|
216
|
-
this.config.debug && console.warn("🧩 pybara-js: recipient access validation failed:", e),
|
|
124
|
+
this.config.debug && console.warn("🧩 pybara-js: recipient access validation failed:", e), a = !0;
|
|
217
125
|
}
|
|
218
126
|
this.modal || this.initCheckoutModal();
|
|
219
|
-
let
|
|
220
|
-
if (!
|
|
221
|
-
if (
|
|
127
|
+
let o = this.modal;
|
|
128
|
+
if (!o) throw this.isOpen = !1, new i("CHECKOUT_FAILED", "The checkout modal could not be initialised.");
|
|
129
|
+
if (a) this.isOpen = !1, o.renderTerminalState("This recipient is currently unable to accept donations."), this.initCheckoutModal();
|
|
222
130
|
else {
|
|
223
131
|
this.activePayment = e;
|
|
224
132
|
try {
|
|
225
|
-
|
|
133
|
+
o.show({
|
|
226
134
|
modalData: {
|
|
227
135
|
beneficiary: this.config.recipientPrincipal,
|
|
228
|
-
salt:
|
|
136
|
+
salt: g(),
|
|
229
137
|
reference: this.config.siteName
|
|
230
138
|
},
|
|
231
139
|
recurring: r,
|
|
232
140
|
checkout: this.checkoutFor(e, t, n)
|
|
233
141
|
});
|
|
234
142
|
} catch (e) {
|
|
235
|
-
throw this.isOpen = !1, this.activePayment = null,
|
|
143
|
+
throw this.isOpen = !1, this.activePayment = null, _(e);
|
|
236
144
|
}
|
|
237
145
|
}
|
|
238
146
|
}
|
|
@@ -256,42 +164,42 @@ var m = /^(0|[1-9]\d*)(\.\d+)?$/, h = /^[a-z0-9-]{1,64}$/, g = class {
|
|
|
256
164
|
r && console.error("🧩 pybara-js: admin client init failed:", e);
|
|
257
165
|
}
|
|
258
166
|
})(), o = (async () => {
|
|
259
|
-
this.config.pluginVersion || (this.gateOutcome = await
|
|
167
|
+
this.config.pluginVersion || (this.gateOutcome = await l(t, this.config.siteUrl, this.config.recipientPrincipal), !this.gateOutcome.show && r && console.warn("🧩 pybara-js: gate refused —", this.gateOutcome.reason));
|
|
260
168
|
})();
|
|
261
169
|
await Promise.all([a, o]);
|
|
262
170
|
}
|
|
263
171
|
initCheckoutModal() {
|
|
264
|
-
let e = this.config.staging ? "staging" : "prod", n = this.config,
|
|
265
|
-
this.modal = new
|
|
172
|
+
let e = this.config.staging ? "staging" : "prod", n = this.config, i = this;
|
|
173
|
+
this.modal = new r({
|
|
266
174
|
walletUrl: t[e],
|
|
267
175
|
context: "donation",
|
|
268
176
|
thankYouMessage: n.thankYouMessage,
|
|
269
177
|
locale: n.locale,
|
|
270
|
-
onAvailability: (e) =>
|
|
178
|
+
onAvailability: (e) => i.emitAvailability(e),
|
|
271
179
|
onSuccess: (e) => {
|
|
272
|
-
|
|
273
|
-
let t =
|
|
180
|
+
i.completedPayment = !0;
|
|
181
|
+
let t = i.activePayment, r = t?.frequency != null, a = {
|
|
274
182
|
blockIndex: e.blockIndex,
|
|
275
183
|
reference: e.reference,
|
|
276
184
|
token: e.token,
|
|
277
|
-
recurring:
|
|
185
|
+
recurring: r,
|
|
278
186
|
frequency: t?.frequency,
|
|
279
|
-
durationMonths:
|
|
280
|
-
isUnlimited:
|
|
187
|
+
durationMonths: r ? t?.durationMonths ?? void 0 : void 0,
|
|
188
|
+
isUnlimited: r && t?.durationMonths == null,
|
|
281
189
|
payerPrincipal: e.payerPrincipal,
|
|
282
190
|
recipientPrincipal: n.recipientPrincipal
|
|
283
191
|
};
|
|
284
192
|
t?.onSuccess?.(a);
|
|
285
193
|
},
|
|
286
194
|
onError: (e) => {
|
|
287
|
-
|
|
288
|
-
let t =
|
|
289
|
-
|
|
195
|
+
i.isOpen = !1;
|
|
196
|
+
let t = i.activePayment;
|
|
197
|
+
i.activePayment = null, t?.onError?.(_(e)), i.modal = null, i.initCheckoutModal();
|
|
290
198
|
},
|
|
291
199
|
onClose: () => {
|
|
292
|
-
|
|
293
|
-
let e =
|
|
294
|
-
|
|
200
|
+
i.isOpen = !1;
|
|
201
|
+
let e = i.activePayment;
|
|
202
|
+
i.activePayment = null, e?.onClose?.(), i.completedPayment && n.thankYouRedirectUrl ? window.location.href = n.thankYouRedirectUrl : (i.completedPayment = !1, i.modal = null, i.initCheckoutModal());
|
|
295
203
|
}
|
|
296
204
|
}), this.availabilityListeners.size > 0 && this.modal && Object.keys(this.lastPrecheck).length > 0 && this.sendPrecheck();
|
|
297
205
|
}
|
|
@@ -347,11 +255,11 @@ var m = /^(0|[1-9]\d*)(\.\d+)?$/, h = /^[a-z0-9-]{1,64}$/, g = class {
|
|
|
347
255
|
n.rel = "preconnect", n.href = new URL(t[e]).origin, n.crossOrigin = "anonymous", document.head.appendChild(n);
|
|
348
256
|
}
|
|
349
257
|
};
|
|
350
|
-
function
|
|
258
|
+
function p(e) {
|
|
351
259
|
let t = typeof e == "number" && Number.isFinite(e) ? String(e) : e;
|
|
352
|
-
return typeof t != "string" || !
|
|
260
|
+
return typeof t != "string" || !u.test(t) || !/[1-9]/.test(t) ? null : t;
|
|
353
261
|
}
|
|
354
|
-
function
|
|
262
|
+
function m(e) {
|
|
355
263
|
let t = e.trim();
|
|
356
264
|
if (!t) return null;
|
|
357
265
|
let n;
|
|
@@ -362,14 +270,14 @@ function v(e) {
|
|
|
362
270
|
}
|
|
363
271
|
return n.protocol !== "https:" && n.protocol !== "http:" ? null : n.origin + n.pathname.replace(/\/+$/, "");
|
|
364
272
|
}
|
|
365
|
-
function
|
|
366
|
-
if (!e.recipientPrincipal) throw new
|
|
367
|
-
if (!e.siteUrl) throw new
|
|
368
|
-
let t =
|
|
369
|
-
if (!t) throw new
|
|
370
|
-
if (!e.siteName) throw new
|
|
371
|
-
if (e.currency != null && !/^[A-Z]{3}$/.test(e.currency)) throw new
|
|
372
|
-
if (e.platform != null && !
|
|
273
|
+
function h(e) {
|
|
274
|
+
if (!e.recipientPrincipal) throw new i("INVALID_CONFIG", "Pybara.checkout: \"recipientPrincipal\" is required");
|
|
275
|
+
if (!e.siteUrl) throw new i("INVALID_CONFIG", "Pybara.checkout: \"siteUrl\" is required");
|
|
276
|
+
let t = m(e.siteUrl);
|
|
277
|
+
if (!t) throw new i("INVALID_CONFIG", `Pybara.checkout: "siteUrl" is not a valid http(s) URL: ${e.siteUrl}`);
|
|
278
|
+
if (!e.siteName) throw new i("INVALID_CONFIG", "Pybara.checkout: \"siteName\" is required");
|
|
279
|
+
if (e.currency != null && !/^[A-Z]{3}$/.test(e.currency)) throw new i("INVALID_CONFIG", `Pybara.checkout: "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(e.currency)}`);
|
|
280
|
+
if (e.platform != null && !d.test(e.platform)) throw new i("INVALID_CONFIG", "Pybara.checkout: \"platform\" must be a lowercase slug (a-z, 0-9, -), at most 64 characters");
|
|
373
281
|
return {
|
|
374
282
|
...e,
|
|
375
283
|
siteUrl: t,
|
|
@@ -377,18 +285,18 @@ function y(e) {
|
|
|
377
285
|
debug: e.debug ?? !1
|
|
378
286
|
};
|
|
379
287
|
}
|
|
380
|
-
function
|
|
288
|
+
function g() {
|
|
381
289
|
let e = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
382
290
|
return btoa(String.fromCharCode(...e));
|
|
383
291
|
}
|
|
384
|
-
function
|
|
292
|
+
function _(e) {
|
|
385
293
|
return e instanceof Error ? e : Error(String(e));
|
|
386
294
|
}
|
|
387
295
|
//#endregion
|
|
388
296
|
//#region src/index.ts
|
|
389
|
-
function
|
|
390
|
-
return new
|
|
297
|
+
function v(e) {
|
|
298
|
+
return new f(e);
|
|
391
299
|
}
|
|
392
|
-
var
|
|
300
|
+
var y = { checkout: v };
|
|
393
301
|
//#endregion
|
|
394
|
-
export {
|
|
302
|
+
export { y as Pybara, f as PybaraCheckout, i as PybaraError, v as checkout };
|
package/dist/types.d.ts
CHANGED
|
@@ -88,17 +88,19 @@ export interface PaymentParams {
|
|
|
88
88
|
}
|
|
89
89
|
/** The payment a button's createPayment() returns: open()'s params, without the callbacks, which buttons() takes itself. */
|
|
90
90
|
export type ButtonPayment = Omit<PaymentParams, 'onSuccess' | 'onError' | 'onClose'>;
|
|
91
|
+
/**
|
|
92
|
+
* The served button's style, passed to it as given and read by it: `color` 'brand' | 'black' | 'white' (PayPal's names; its 'gold', 'blue' and 'silver' read as 'brand'), `shape` 'pill' | 'rect' | 'sharp', `height` 25–55 px (PayPal's range, default 45), and `borderRadius` in pixels, 0 or more, which overrides the shape's corners, as PayPal's.
|
|
93
|
+
* Copy a PayPal button's style and the two match. A value the button doesn't know falls back to its default.
|
|
94
|
+
*/
|
|
95
|
+
export interface ButtonStyle {
|
|
96
|
+
color?: string;
|
|
97
|
+
shape?: string;
|
|
98
|
+
height?: number;
|
|
99
|
+
borderRadius?: number;
|
|
100
|
+
}
|
|
91
101
|
/** Options for checkout.buttons(): a "Pybara" button, served by Pybara, that opens this checkout on click. */
|
|
92
102
|
export interface ButtonsOptions {
|
|
93
|
-
|
|
94
|
-
* Passed to the button as given, and read by it: `color` 'brand' | 'black' | 'white' (PayPal's names; its 'gold', 'blue' and 'silver' read as 'brand'), `shape` 'pill' | 'rect' | 'sharp', `height` 25–55 px (PayPal's range, default 45).
|
|
95
|
-
* Copy a PayPal button's style and the two match. A value the button doesn't know falls back to its default.
|
|
96
|
-
*/
|
|
97
|
-
style?: {
|
|
98
|
-
color?: string;
|
|
99
|
-
shape?: string;
|
|
100
|
-
height?: number;
|
|
101
|
-
};
|
|
103
|
+
style?: ButtonStyle;
|
|
102
104
|
/** Collapse the button to no height when Pybara is unavailable on this page; by default its slot stays, empty, so the layout never moves. */
|
|
103
105
|
hideWhenUnavailable?: boolean;
|
|
104
106
|
/** Called on the payer's click: the payment from the form's current values, as open() takes it (amount, currency, frequency, donor fields). */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pybara/pybara-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Accept crypto payments and donations with Pybara on any page — a callable checkout, in the stripe-js / paypal-js convention.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pybara",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./dist/modal/index.d.ts",
|
|
33
33
|
"import": "./dist/modal/index.js"
|
|
34
34
|
},
|
|
35
|
+
"./button": {
|
|
36
|
+
"types": "./dist/button/index.d.ts",
|
|
37
|
+
"import": "./dist/button/index.js"
|
|
38
|
+
},
|
|
35
39
|
"./dist/pybara-js.iife.js": "./dist/pybara-js.iife.js",
|
|
36
40
|
"./package.json": "./package.json"
|
|
37
41
|
},
|
|
@@ -43,7 +47,7 @@
|
|
|
43
47
|
"build": "vite build && vite build -c vite.config.iife.ts",
|
|
44
48
|
"prepare": "npm run build",
|
|
45
49
|
"type-check": "tsc --noEmit",
|
|
46
|
-
"prepublishOnly": "npm run type-check && npm run build",
|
|
50
|
+
"prepublishOnly": "npm run type-check && node scripts/check-readme-version.mjs && npm run build",
|
|
47
51
|
"release:tag": "git tag v$npm_package_version && git push origin v$npm_package_version",
|
|
48
52
|
"demo": "node demo/load-env.mjs && (sleep 1 && open http://localhost:5678 &) && npx serve demo -l 5678",
|
|
49
53
|
"dev": "vite --open /demo/"
|
package/dist/buttons.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Availability } from './modal/modal';
|
|
2
|
-
import { ButtonsOptions, PaymentParams, PybaraButtons } from './types';
|
|
3
|
-
/** What the loader needs from its checkout: the frame's origin, open(), and the availability answers. */
|
|
4
|
-
export interface ButtonsHost {
|
|
5
|
-
walletUrl: string;
|
|
6
|
-
open(payment: PaymentParams): Promise<void>;
|
|
7
|
-
/** Subscribes to every availability answer, first with the latest one if there is one; returns the unsubscribe. */
|
|
8
|
-
subscribeAvailability(listener: (availability: Availability) => void): () => void;
|
|
9
|
-
}
|
|
10
|
-
export declare function createButtons(host: ButtonsHost, options: ButtonsOptions): PybaraButtons;
|
|
11
|
-
//# sourceMappingURL=buttons.d.ts.map
|
package/dist/buttons.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"buttons.d.ts","sourceRoot":"","sources":["../src/buttons.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAe,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAEnG,yGAAyG;AACzG,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,mHAAmH;IACnH,qBAAqB,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACnF;AAoBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,CAmGvF"}
|