@burdenoff/website-sdk 2026.824.2 → 2026.828.1
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 +88 -0
- package/dist/client/index.d.mts +2 -3
- package/dist/client/index.d.ts +2 -3
- package/dist/client/index.js +13 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +13 -7
- package/dist/client/index.mjs.map +1 -1
- package/dist/components/contact.d.mts +2 -2
- package/dist/components/contact.d.ts +2 -2
- package/dist/components/contact.js +13 -7
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +13 -7
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/electron-download.d.mts +2 -2
- package/dist/components/electron-download.d.ts +2 -2
- package/dist/components/explore-cta.d.mts +26 -0
- package/dist/components/explore-cta.d.ts +26 -0
- package/dist/components/explore-cta.js +95 -0
- package/dist/components/explore-cta.js.map +1 -0
- package/dist/components/explore-cta.mjs +93 -0
- package/dist/components/explore-cta.mjs.map +1 -0
- package/dist/components/explore.d.mts +43 -0
- package/dist/components/explore.d.ts +43 -0
- package/dist/components/explore.js +2219 -0
- package/dist/components/explore.js.map +1 -0
- package/dist/components/explore.mjs +2193 -0
- package/dist/components/explore.mjs.map +1 -0
- package/dist/components/launch-countdown.d.mts +2 -2
- package/dist/components/launch-countdown.d.ts +2 -2
- package/dist/components/newsletter.d.mts +3 -3
- package/dist/components/newsletter.d.ts +3 -3
- package/dist/components/newsletter.js +13 -7
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +13 -7
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.d.mts +2 -2
- package/dist/components/partners.d.ts +2 -2
- package/dist/components/partners.js +13 -7
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +13 -7
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.d.mts +3 -3
- package/dist/components/pricing.d.ts +3 -3
- package/dist/components/pricing.js +13 -7
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +13 -7
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/problems-solved.d.mts +2 -2
- package/dist/components/problems-solved.d.ts +2 -2
- package/dist/components/resource-links.d.mts +2 -2
- package/dist/components/resource-links.d.ts +2 -2
- package/dist/components/resource-links.js +13 -7
- package/dist/components/resource-links.js.map +1 -1
- package/dist/components/resource-links.mjs +13 -7
- package/dist/components/resource-links.mjs.map +1 -1
- package/dist/components/social-links.d.mts +2 -2
- package/dist/components/social-links.d.ts +2 -2
- package/dist/components/social-links.js +13 -7
- package/dist/components/social-links.js.map +1 -1
- package/dist/components/social-links.mjs +13 -7
- package/dist/components/social-links.mjs.map +1 -1
- package/dist/components/unsubscribe.d.mts +2 -2
- package/dist/components/unsubscribe.d.ts +2 -2
- package/dist/components/unsubscribe.js +13 -7
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +13 -7
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.d.mts +3 -3
- package/dist/components/waitlist.d.ts +3 -3
- package/dist/components/waitlist.js +13 -7
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +13 -7
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/components/website-switcher.d.mts +2 -2
- package/dist/components/website-switcher.d.ts +2 -2
- package/dist/content/index.d.mts +2 -3
- package/dist/content/index.d.ts +2 -3
- package/dist/content/index.js +13 -7
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +13 -7
- package/dist/content/index.mjs.map +1 -1
- package/dist/{graphql-client-Cv6TO6hn.d.mts → graphql-client-BXn6RYV0.d.mts} +31 -4
- package/dist/{graphql-client-Cv6TO6hn.d.ts → graphql-client-BXn6RYV0.d.ts} +31 -4
- package/dist/hooks/index.d.mts +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1145 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +1140 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/{index-CFsUFxYo.d.ts → index-BXg7cQLm.d.ts} +11 -11
- package/dist/index-CUJTTlYx.d.mts +244 -0
- package/dist/index-CUJTTlYx.d.ts +244 -0
- package/dist/{index-CuMRiKGB.d.mts → index-DYxQiEm5.d.mts} +11 -11
- package/dist/index.d.mts +17 -15
- package/dist/index.d.ts +17 -15
- package/dist/index.js +1987 -426
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1977 -428
- package/dist/index.mjs.map +1 -1
- package/dist/product/index.d.mts +2 -2
- package/dist/product/index.d.ts +2 -2
- package/dist/product/index.js +13 -7
- package/dist/product/index.js.map +1 -1
- package/dist/product/index.mjs +13 -7
- package/dist/product/index.mjs.map +1 -1
- package/dist/{product-card-DL9O3Ez9.d.mts → product-card-CGxETsFa.d.mts} +7 -7
- package/dist/{product-card-DL9O3Ez9.d.ts → product-card-CGxETsFa.d.ts} +7 -7
- package/dist/{provider-D-Do5PmD.d.ts → provider-CUfI8meE.d.mts} +3 -3
- package/dist/{provider-BhsbxVPo.d.mts → provider-D_uUM7_e.d.ts} +3 -3
- package/dist/seo/index.d.mts +2 -2
- package/dist/seo/index.d.ts +2 -2
- package/dist/store/index.d.mts +3 -3
- package/dist/store/index.d.ts +3 -3
- package/dist/store/index.js +13 -7
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +13 -7
- package/dist/store/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +49 -1
- package/dist/utils/index.d.ts +49 -1
- package/dist/utils/index.js +70 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +68 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +40 -30
package/dist/utils/index.d.mts
CHANGED
|
@@ -18,4 +18,52 @@ import { ClassValue } from 'clsx';
|
|
|
18
18
|
*/
|
|
19
19
|
declare function cn(...inputs: ClassValue[]): string;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* reCAPTCHA v3 (invisible, score-based) loader and token minter.
|
|
23
|
+
*
|
|
24
|
+
* Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`
|
|
25
|
+
* peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot
|
|
26
|
+
* share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have
|
|
27
|
+
* it. This module injects its own v3 script and leaves the v2 integration alone.
|
|
28
|
+
*
|
|
29
|
+
* The Explore chat turns v3 on purely from the backend catalog
|
|
30
|
+
* (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded
|
|
31
|
+
* and no third-party request is made on sites where captcha is off.
|
|
32
|
+
*/
|
|
33
|
+
/** The slice of the `grecaptcha` global this module uses. */
|
|
34
|
+
interface RecaptchaV3 {
|
|
35
|
+
/** Runs the callback once the API is fully initialised. */
|
|
36
|
+
ready(callback: () => void): void;
|
|
37
|
+
/** Mints a single-use token for `action`. */
|
|
38
|
+
execute(siteKey: string, options: {
|
|
39
|
+
action: string;
|
|
40
|
+
}): Promise<string>;
|
|
41
|
+
}
|
|
42
|
+
declare global {
|
|
43
|
+
interface Window {
|
|
44
|
+
grecaptcha?: RecaptchaV3;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Default action name reported to reCAPTCHA for Explore chat submissions. */
|
|
48
|
+
declare const EXPLORE_RECAPTCHA_ACTION = "explore_chat";
|
|
49
|
+
/**
|
|
50
|
+
* Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is
|
|
51
|
+
* ready to mint tokens.
|
|
52
|
+
*
|
|
53
|
+
* - Injects the script at most once per site key (subsequent calls reuse the
|
|
54
|
+
* same promise).
|
|
55
|
+
* - Adopts an already-present script tag (e.g. injected by the host site)
|
|
56
|
+
* rather than adding a second one.
|
|
57
|
+
* - Rejects rather than hanging when the script fails to load, so the caller
|
|
58
|
+
* can decide whether to submit without a token or surface an error.
|
|
59
|
+
*/
|
|
60
|
+
declare function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3>;
|
|
61
|
+
/**
|
|
62
|
+
* Mint a single-use reCAPTCHA v3 token, loading the script on first use.
|
|
63
|
+
*
|
|
64
|
+
* Tokens are valid for ~2 minutes and are consumed by one verification, so
|
|
65
|
+
* this must be called per submission — never cached.
|
|
66
|
+
*/
|
|
67
|
+
declare function getRecaptchaV3Token(siteKey: string, action?: string): Promise<string>;
|
|
68
|
+
|
|
69
|
+
export { EXPLORE_RECAPTCHA_ACTION, type RecaptchaV3, cn, getRecaptchaV3Token, loadRecaptchaV3 };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -18,4 +18,52 @@ import { ClassValue } from 'clsx';
|
|
|
18
18
|
*/
|
|
19
19
|
declare function cn(...inputs: ClassValue[]): string;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* reCAPTCHA v3 (invisible, score-based) loader and token minter.
|
|
23
|
+
*
|
|
24
|
+
* Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`
|
|
25
|
+
* peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot
|
|
26
|
+
* share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have
|
|
27
|
+
* it. This module injects its own v3 script and leaves the v2 integration alone.
|
|
28
|
+
*
|
|
29
|
+
* The Explore chat turns v3 on purely from the backend catalog
|
|
30
|
+
* (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded
|
|
31
|
+
* and no third-party request is made on sites where captcha is off.
|
|
32
|
+
*/
|
|
33
|
+
/** The slice of the `grecaptcha` global this module uses. */
|
|
34
|
+
interface RecaptchaV3 {
|
|
35
|
+
/** Runs the callback once the API is fully initialised. */
|
|
36
|
+
ready(callback: () => void): void;
|
|
37
|
+
/** Mints a single-use token for `action`. */
|
|
38
|
+
execute(siteKey: string, options: {
|
|
39
|
+
action: string;
|
|
40
|
+
}): Promise<string>;
|
|
41
|
+
}
|
|
42
|
+
declare global {
|
|
43
|
+
interface Window {
|
|
44
|
+
grecaptcha?: RecaptchaV3;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Default action name reported to reCAPTCHA for Explore chat submissions. */
|
|
48
|
+
declare const EXPLORE_RECAPTCHA_ACTION = "explore_chat";
|
|
49
|
+
/**
|
|
50
|
+
* Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is
|
|
51
|
+
* ready to mint tokens.
|
|
52
|
+
*
|
|
53
|
+
* - Injects the script at most once per site key (subsequent calls reuse the
|
|
54
|
+
* same promise).
|
|
55
|
+
* - Adopts an already-present script tag (e.g. injected by the host site)
|
|
56
|
+
* rather than adding a second one.
|
|
57
|
+
* - Rejects rather than hanging when the script fails to load, so the caller
|
|
58
|
+
* can decide whether to submit without a token or surface an error.
|
|
59
|
+
*/
|
|
60
|
+
declare function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3>;
|
|
61
|
+
/**
|
|
62
|
+
* Mint a single-use reCAPTCHA v3 token, loading the script on first use.
|
|
63
|
+
*
|
|
64
|
+
* Tokens are valid for ~2 minutes and are consumed by one verification, so
|
|
65
|
+
* this must be called per submission — never cached.
|
|
66
|
+
*/
|
|
67
|
+
declare function getRecaptchaV3Token(siteKey: string, action?: string): Promise<string>;
|
|
68
|
+
|
|
69
|
+
export { EXPLORE_RECAPTCHA_ACTION, type RecaptchaV3, cn, getRecaptchaV3Token, loadRecaptchaV3 };
|
package/dist/utils/index.js
CHANGED
|
@@ -7,6 +7,76 @@ function cn(...inputs) {
|
|
|
7
7
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// src/utils/recaptcha-v3.ts
|
|
11
|
+
var SCRIPT_ID = "boff-recaptcha-v3";
|
|
12
|
+
var SCRIPT_SRC = "https://www.google.com/recaptcha/api.js?render=";
|
|
13
|
+
var EXPLORE_RECAPTCHA_ACTION = "explore_chat";
|
|
14
|
+
var loaders = /* @__PURE__ */ new Map();
|
|
15
|
+
function isBrowser() {
|
|
16
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
17
|
+
}
|
|
18
|
+
function loadRecaptchaV3(siteKey) {
|
|
19
|
+
if (!siteKey) {
|
|
20
|
+
return Promise.reject(new Error("reCAPTCHA site key is required"));
|
|
21
|
+
}
|
|
22
|
+
if (!isBrowser()) {
|
|
23
|
+
return Promise.reject(
|
|
24
|
+
new Error("reCAPTCHA v3 can only be loaded in a browser")
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const existing = loaders.get(siteKey);
|
|
28
|
+
if (existing) return existing;
|
|
29
|
+
const promise = new Promise((resolve, reject) => {
|
|
30
|
+
const ready = () => {
|
|
31
|
+
const api = window.grecaptcha;
|
|
32
|
+
if (!api) {
|
|
33
|
+
reject(new Error("reCAPTCHA loaded but grecaptcha is unavailable"));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
api.ready(() => resolve(api));
|
|
37
|
+
};
|
|
38
|
+
if (window.grecaptcha) {
|
|
39
|
+
ready();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const scriptId = `${SCRIPT_ID}-${siteKey}`;
|
|
43
|
+
const found = document.getElementById(scriptId);
|
|
44
|
+
if (found) {
|
|
45
|
+
found.addEventListener("load", ready, { once: true });
|
|
46
|
+
found.addEventListener(
|
|
47
|
+
"error",
|
|
48
|
+
() => reject(new Error("Failed to load reCAPTCHA v3")),
|
|
49
|
+
{ once: true }
|
|
50
|
+
);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const script = document.createElement("script");
|
|
54
|
+
script.id = scriptId;
|
|
55
|
+
script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;
|
|
56
|
+
script.async = true;
|
|
57
|
+
script.defer = true;
|
|
58
|
+
script.addEventListener("load", ready, { once: true });
|
|
59
|
+
script.addEventListener(
|
|
60
|
+
"error",
|
|
61
|
+
() => {
|
|
62
|
+
loaders.delete(siteKey);
|
|
63
|
+
reject(new Error("Failed to load reCAPTCHA v3"));
|
|
64
|
+
},
|
|
65
|
+
{ once: true }
|
|
66
|
+
);
|
|
67
|
+
document.head.appendChild(script);
|
|
68
|
+
});
|
|
69
|
+
loaders.set(siteKey, promise);
|
|
70
|
+
return promise;
|
|
71
|
+
}
|
|
72
|
+
async function getRecaptchaV3Token(siteKey, action = EXPLORE_RECAPTCHA_ACTION) {
|
|
73
|
+
const api = await loadRecaptchaV3(siteKey);
|
|
74
|
+
return api.execute(siteKey, { action });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exports.EXPLORE_RECAPTCHA_ACTION = EXPLORE_RECAPTCHA_ACTION;
|
|
10
78
|
exports.cn = cn;
|
|
79
|
+
exports.getRecaptchaV3Token = getRecaptchaV3Token;
|
|
80
|
+
exports.loadRecaptchaV3 = loadRecaptchaV3;
|
|
11
81
|
//# sourceMappingURL=index.js.map
|
|
12
82
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/cn.ts"],"names":["twMerge","clsx"],"mappings":";;;;;AAmBO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"index.js","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/utils/recaptcha-v3.ts"],"names":["twMerge","clsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * reCAPTCHA v3 (invisible, score-based) loader and token minter.\n *\n * Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`\n * peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot\n * share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have\n * it. This module injects its own v3 script and leaves the v2 integration alone.\n *\n * The Explore chat turns v3 on purely from the backend catalog\n * (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded\n * and no third-party request is made on sites where captcha is off.\n */\n\n/** The slice of the `grecaptcha` global this module uses. */\nexport interface RecaptchaV3 {\n /** Runs the callback once the API is fully initialised. */\n ready(callback: () => void): void;\n /** Mints a single-use token for `action`. */\n execute(siteKey: string, options: { action: string }): Promise<string>;\n}\n\ndeclare global {\n interface Window {\n grecaptcha?: RecaptchaV3;\n }\n}\n\nconst SCRIPT_ID = \"boff-recaptcha-v3\";\nconst SCRIPT_SRC = \"https://www.google.com/recaptcha/api.js?render=\";\n\n/** Default action name reported to reCAPTCHA for Explore chat submissions. */\nexport const EXPLORE_RECAPTCHA_ACTION = \"explore_chat\";\n\n/**\n * One in-flight/settled promise per site key. Guarantees the script tag is\n * injected at most once even when several components mount at the same time,\n * and lets later callers await the same load instead of racing it.\n */\nconst loaders = new Map<string, Promise<RecaptchaV3>>();\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/**\n * Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is\n * ready to mint tokens.\n *\n * - Injects the script at most once per site key (subsequent calls reuse the\n * same promise).\n * - Adopts an already-present script tag (e.g. injected by the host site)\n * rather than adding a second one.\n * - Rejects rather than hanging when the script fails to load, so the caller\n * can decide whether to submit without a token or surface an error.\n */\nexport function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3> {\n if (!siteKey) {\n return Promise.reject(new Error(\"reCAPTCHA site key is required\"));\n }\n if (!isBrowser()) {\n return Promise.reject(\n new Error(\"reCAPTCHA v3 can only be loaded in a browser\"),\n );\n }\n\n const existing = loaders.get(siteKey);\n if (existing) return existing;\n\n const promise = new Promise<RecaptchaV3>((resolve, reject) => {\n const ready = () => {\n const api = window.grecaptcha;\n if (!api) {\n reject(new Error(\"reCAPTCHA loaded but grecaptcha is unavailable\"));\n return;\n }\n // `ready` queues until the API has finished initialising internally;\n // calling `execute` before that throws.\n api.ready(() => resolve(api));\n };\n\n // Already loaded by this module, another SDK instance, or the host site.\n if (window.grecaptcha) {\n ready();\n return;\n }\n\n const scriptId = `${SCRIPT_ID}-${siteKey}`;\n const found = document.getElementById(scriptId);\n if (found) {\n found.addEventListener(\"load\", ready, { once: true });\n found.addEventListener(\n \"error\",\n () => reject(new Error(\"Failed to load reCAPTCHA v3\")),\n { once: true },\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.id = scriptId;\n script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;\n script.async = true;\n script.defer = true;\n script.addEventListener(\"load\", ready, { once: true });\n script.addEventListener(\n \"error\",\n () => {\n // Drop the memo so a later attempt can retry a transient CDN failure\n // instead of being stuck with a permanently rejected promise.\n loaders.delete(siteKey);\n reject(new Error(\"Failed to load reCAPTCHA v3\"));\n },\n { once: true },\n );\n document.head.appendChild(script);\n });\n\n loaders.set(siteKey, promise);\n return promise;\n}\n\n/**\n * Mint a single-use reCAPTCHA v3 token, loading the script on first use.\n *\n * Tokens are valid for ~2 minutes and are consumed by one verification, so\n * this must be called per submission — never cached.\n */\nexport async function getRecaptchaV3Token(\n siteKey: string,\n action: string = EXPLORE_RECAPTCHA_ACTION,\n): Promise<string> {\n const api = await loadRecaptchaV3(siteKey);\n return api.execute(siteKey, { action });\n}\n"]}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -5,6 +5,73 @@ function cn(...inputs) {
|
|
|
5
5
|
return twMerge(clsx(inputs));
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
// src/utils/recaptcha-v3.ts
|
|
9
|
+
var SCRIPT_ID = "boff-recaptcha-v3";
|
|
10
|
+
var SCRIPT_SRC = "https://www.google.com/recaptcha/api.js?render=";
|
|
11
|
+
var EXPLORE_RECAPTCHA_ACTION = "explore_chat";
|
|
12
|
+
var loaders = /* @__PURE__ */ new Map();
|
|
13
|
+
function isBrowser() {
|
|
14
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
15
|
+
}
|
|
16
|
+
function loadRecaptchaV3(siteKey) {
|
|
17
|
+
if (!siteKey) {
|
|
18
|
+
return Promise.reject(new Error("reCAPTCHA site key is required"));
|
|
19
|
+
}
|
|
20
|
+
if (!isBrowser()) {
|
|
21
|
+
return Promise.reject(
|
|
22
|
+
new Error("reCAPTCHA v3 can only be loaded in a browser")
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
const existing = loaders.get(siteKey);
|
|
26
|
+
if (existing) return existing;
|
|
27
|
+
const promise = new Promise((resolve, reject) => {
|
|
28
|
+
const ready = () => {
|
|
29
|
+
const api = window.grecaptcha;
|
|
30
|
+
if (!api) {
|
|
31
|
+
reject(new Error("reCAPTCHA loaded but grecaptcha is unavailable"));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
api.ready(() => resolve(api));
|
|
35
|
+
};
|
|
36
|
+
if (window.grecaptcha) {
|
|
37
|
+
ready();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const scriptId = `${SCRIPT_ID}-${siteKey}`;
|
|
41
|
+
const found = document.getElementById(scriptId);
|
|
42
|
+
if (found) {
|
|
43
|
+
found.addEventListener("load", ready, { once: true });
|
|
44
|
+
found.addEventListener(
|
|
45
|
+
"error",
|
|
46
|
+
() => reject(new Error("Failed to load reCAPTCHA v3")),
|
|
47
|
+
{ once: true }
|
|
48
|
+
);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const script = document.createElement("script");
|
|
52
|
+
script.id = scriptId;
|
|
53
|
+
script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;
|
|
54
|
+
script.async = true;
|
|
55
|
+
script.defer = true;
|
|
56
|
+
script.addEventListener("load", ready, { once: true });
|
|
57
|
+
script.addEventListener(
|
|
58
|
+
"error",
|
|
59
|
+
() => {
|
|
60
|
+
loaders.delete(siteKey);
|
|
61
|
+
reject(new Error("Failed to load reCAPTCHA v3"));
|
|
62
|
+
},
|
|
63
|
+
{ once: true }
|
|
64
|
+
);
|
|
65
|
+
document.head.appendChild(script);
|
|
66
|
+
});
|
|
67
|
+
loaders.set(siteKey, promise);
|
|
68
|
+
return promise;
|
|
69
|
+
}
|
|
70
|
+
async function getRecaptchaV3Token(siteKey, action = EXPLORE_RECAPTCHA_ACTION) {
|
|
71
|
+
const api = await loadRecaptchaV3(siteKey);
|
|
72
|
+
return api.execute(siteKey, { action });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { EXPLORE_RECAPTCHA_ACTION, cn, getRecaptchaV3Token, loadRecaptchaV3 };
|
|
9
76
|
//# sourceMappingURL=index.mjs.map
|
|
10
77
|
//# sourceMappingURL=index.mjs.map
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/cn.ts"],"names":[],"mappings":";;;AAmBO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"index.mjs","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/utils/recaptcha-v3.ts"],"names":[],"mappings":";;;AAmBO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;;;ACMA,IAAM,SAAA,GAAY,mBAAA;AAClB,IAAM,UAAA,GAAa,iDAAA;AAGZ,IAAM,wBAAA,GAA2B;AAOxC,IAAM,OAAA,uBAAc,GAAA,EAAkC;AAEtD,SAAS,SAAA,GAAqB;AAC5B,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,QAAA,KAAa,WAAA;AAC9D;AAaO,SAAS,gBAAgB,OAAA,EAAuC;AACrE,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,gCAAgC,CAAC,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,CAAC,WAAU,EAAG;AAChB,IAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,MACb,IAAI,MAAM,8CAA8C;AAAA,KAC1D;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA;AACpC,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAqB,CAAC,SAAS,MAAA,KAAW;AAC5D,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,MAAM,MAAM,MAAA,CAAO,UAAA;AACnB,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,gDAAgD,CAAC,CAAA;AAClE,QAAA;AAAA,MACF;AAGA,MAAA,GAAA,CAAI,KAAA,CAAM,MAAM,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,IAC9B,CAAA;AAGA,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,KAAA,EAAM;AACN,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AACxC,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,cAAA,CAAe,QAAQ,CAAA;AAC9C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,CAAM,iBAAiB,MAAA,EAAQ,KAAA,EAAO,EAAE,IAAA,EAAM,MAAM,CAAA;AACpD,MAAA,KAAA,CAAM,gBAAA;AAAA,QACJ,OAAA;AAAA,QACA,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,6BAA6B,CAAC,CAAA;AAAA,QACrD,EAAE,MAAM,IAAA;AAAK,OACf;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,EAAA,GAAK,QAAA;AACZ,IAAA,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,CAAA,EAAG,kBAAA,CAAmB,OAAO,CAAC,CAAA,CAAA;AACxD,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,iBAAiB,MAAA,EAAQ,KAAA,EAAO,EAAE,IAAA,EAAM,MAAM,CAAA;AACrD,IAAA,MAAA,CAAO,gBAAA;AAAA,MACL,OAAA;AAAA,MACA,MAAM;AAGJ,QAAA,OAAA,CAAQ,OAAO,OAAO,CAAA;AACtB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,6BAA6B,CAAC,CAAA;AAAA,MACjD,CAAA;AAAA,MACA,EAAE,MAAM,IAAA;AAAK,KACf;AACA,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,GAAA,CAAI,SAAS,OAAO,CAAA;AAC5B,EAAA,OAAO,OAAA;AACT;AAQA,eAAsB,mBAAA,CACpB,OAAA,EACA,MAAA,GAAiB,wBAAA,EACA;AACjB,EAAA,MAAM,GAAA,GAAM,MAAM,eAAA,CAAgB,OAAO,CAAA;AACzC,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,OAAA,EAAS,EAAE,QAAQ,CAAA;AACxC","file":"index.mjs","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * reCAPTCHA v3 (invisible, score-based) loader and token minter.\n *\n * Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`\n * peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot\n * share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have\n * it. This module injects its own v3 script and leaves the v2 integration alone.\n *\n * The Explore chat turns v3 on purely from the backend catalog\n * (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded\n * and no third-party request is made on sites where captcha is off.\n */\n\n/** The slice of the `grecaptcha` global this module uses. */\nexport interface RecaptchaV3 {\n /** Runs the callback once the API is fully initialised. */\n ready(callback: () => void): void;\n /** Mints a single-use token for `action`. */\n execute(siteKey: string, options: { action: string }): Promise<string>;\n}\n\ndeclare global {\n interface Window {\n grecaptcha?: RecaptchaV3;\n }\n}\n\nconst SCRIPT_ID = \"boff-recaptcha-v3\";\nconst SCRIPT_SRC = \"https://www.google.com/recaptcha/api.js?render=\";\n\n/** Default action name reported to reCAPTCHA for Explore chat submissions. */\nexport const EXPLORE_RECAPTCHA_ACTION = \"explore_chat\";\n\n/**\n * One in-flight/settled promise per site key. Guarantees the script tag is\n * injected at most once even when several components mount at the same time,\n * and lets later callers await the same load instead of racing it.\n */\nconst loaders = new Map<string, Promise<RecaptchaV3>>();\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/**\n * Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is\n * ready to mint tokens.\n *\n * - Injects the script at most once per site key (subsequent calls reuse the\n * same promise).\n * - Adopts an already-present script tag (e.g. injected by the host site)\n * rather than adding a second one.\n * - Rejects rather than hanging when the script fails to load, so the caller\n * can decide whether to submit without a token or surface an error.\n */\nexport function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3> {\n if (!siteKey) {\n return Promise.reject(new Error(\"reCAPTCHA site key is required\"));\n }\n if (!isBrowser()) {\n return Promise.reject(\n new Error(\"reCAPTCHA v3 can only be loaded in a browser\"),\n );\n }\n\n const existing = loaders.get(siteKey);\n if (existing) return existing;\n\n const promise = new Promise<RecaptchaV3>((resolve, reject) => {\n const ready = () => {\n const api = window.grecaptcha;\n if (!api) {\n reject(new Error(\"reCAPTCHA loaded but grecaptcha is unavailable\"));\n return;\n }\n // `ready` queues until the API has finished initialising internally;\n // calling `execute` before that throws.\n api.ready(() => resolve(api));\n };\n\n // Already loaded by this module, another SDK instance, or the host site.\n if (window.grecaptcha) {\n ready();\n return;\n }\n\n const scriptId = `${SCRIPT_ID}-${siteKey}`;\n const found = document.getElementById(scriptId);\n if (found) {\n found.addEventListener(\"load\", ready, { once: true });\n found.addEventListener(\n \"error\",\n () => reject(new Error(\"Failed to load reCAPTCHA v3\")),\n { once: true },\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.id = scriptId;\n script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;\n script.async = true;\n script.defer = true;\n script.addEventListener(\"load\", ready, { once: true });\n script.addEventListener(\n \"error\",\n () => {\n // Drop the memo so a later attempt can retry a transient CDN failure\n // instead of being stuck with a permanently rejected promise.\n loaders.delete(siteKey);\n reject(new Error(\"Failed to load reCAPTCHA v3\"));\n },\n { once: true },\n );\n document.head.appendChild(script);\n });\n\n loaders.set(siteKey, promise);\n return promise;\n}\n\n/**\n * Mint a single-use reCAPTCHA v3 token, loading the script on first use.\n *\n * Tokens are valid for ~2 minutes and are consumed by one verification, so\n * this must be called per submission — never cached.\n */\nexport async function getRecaptchaV3Token(\n siteKey: string,\n action: string = EXPLORE_RECAPTCHA_ACTION,\n): Promise<string> {\n const api = await loadRecaptchaV3(siteKey);\n return api.execute(siteKey, { action });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/website-sdk",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.828.1",
|
|
4
4
|
"description": "Shared SDK for Burdenoff product websites - reusable React components, utilities, and configurations",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,6 +41,11 @@
|
|
|
41
41
|
"import": "./dist/product/index.mjs",
|
|
42
42
|
"require": "./dist/product/index.js"
|
|
43
43
|
},
|
|
44
|
+
"./hooks": {
|
|
45
|
+
"types": "./dist/hooks/index.d.ts",
|
|
46
|
+
"import": "./dist/hooks/index.mjs",
|
|
47
|
+
"require": "./dist/hooks/index.js"
|
|
48
|
+
},
|
|
44
49
|
"./utils": {
|
|
45
50
|
"types": "./dist/utils/index.d.ts",
|
|
46
51
|
"import": "./dist/utils/index.mjs",
|
|
@@ -112,49 +117,49 @@
|
|
|
112
117
|
"zod": ">=3.0.0"
|
|
113
118
|
},
|
|
114
119
|
"dependencies": {
|
|
115
|
-
"isomorphic-dompurify": "^2.
|
|
120
|
+
"isomorphic-dompurify": "^2.36.0",
|
|
116
121
|
"react-markdown": "^10.1.0",
|
|
117
122
|
"rehype-sanitize": "^6.0.0",
|
|
118
123
|
"remark-gfm": "^4.0.1"
|
|
119
124
|
},
|
|
120
125
|
"devDependencies": {
|
|
121
|
-
"@eslint/js": "^9.39.
|
|
122
|
-
"@hookform/resolvers": "^5.
|
|
123
|
-
"@radix-ui/react-dropdown-menu": "^2.1.
|
|
124
|
-
"@radix-ui/react-label": "^2.
|
|
125
|
-
"@radix-ui/react-slot": "^1.
|
|
126
|
+
"@eslint/js": "^9.39.5",
|
|
127
|
+
"@hookform/resolvers": "^5.9.1",
|
|
128
|
+
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
|
129
|
+
"@radix-ui/react-label": "^2.1.15",
|
|
130
|
+
"@radix-ui/react-slot": "^1.3.3",
|
|
126
131
|
"@testing-library/react": "^16.3.2",
|
|
127
|
-
"@types/node": "^22.
|
|
128
|
-
"@types/react": "^18.3.
|
|
129
|
-
"@types/react-dom": "^18.3.
|
|
132
|
+
"@types/node": "^22.20.1",
|
|
133
|
+
"@types/react": "^18.3.31",
|
|
134
|
+
"@types/react-dom": "^18.3.7",
|
|
130
135
|
"@types/react-google-recaptcha": "^2.1.9",
|
|
131
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
132
|
-
"@typescript-eslint/parser": "^8.
|
|
133
|
-
"@vitest/coverage-v8": "^4.
|
|
136
|
+
"@typescript-eslint/eslint-plugin": "^8.68.0",
|
|
137
|
+
"@typescript-eslint/parser": "^8.68.0",
|
|
138
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
134
139
|
"class-variance-authority": "^0.7.1",
|
|
135
140
|
"clsx": "^2.1.1",
|
|
136
|
-
"eslint": "^9.
|
|
141
|
+
"eslint": "^9.39.5",
|
|
137
142
|
"eslint-config-prettier": "^10.1.8",
|
|
138
|
-
"eslint-import-resolver-typescript": "^4.4.
|
|
143
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
139
144
|
"eslint-plugin-import": "^2.32.0",
|
|
140
145
|
"eslint-plugin-react": "^7.37.5",
|
|
141
|
-
"eslint-plugin-react-hooks": "^5.
|
|
146
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
142
147
|
"globals": "^16.5.0",
|
|
143
|
-
"jsdom": "^24.
|
|
148
|
+
"jsdom": "^24.1.3",
|
|
144
149
|
"lucide-react": "^0.462.0",
|
|
145
|
-
"prettier": "^3.6
|
|
150
|
+
"prettier": "^3.9.6",
|
|
146
151
|
"react": "^18.3.1",
|
|
147
152
|
"react-dom": "^18.3.1",
|
|
148
153
|
"react-google-recaptcha": "^3.1.0",
|
|
149
154
|
"react-helmet-async": "^2.0.5",
|
|
150
|
-
"react-hook-form": "^7.
|
|
151
|
-
"sonner": "^2.0.
|
|
152
|
-
"tailwind-merge": "^3.
|
|
153
|
-
"tsup": "^8.
|
|
154
|
-
"typescript": "^5.
|
|
155
|
-
"typescript-eslint": "^8.
|
|
156
|
-
"vitest": "^4.
|
|
157
|
-
"zod": "^3.25.
|
|
155
|
+
"react-hook-form": "^7.86.0",
|
|
156
|
+
"sonner": "^2.0.8",
|
|
157
|
+
"tailwind-merge": "^3.6.0",
|
|
158
|
+
"tsup": "^8.5.1",
|
|
159
|
+
"typescript": "^5.9.3",
|
|
160
|
+
"typescript-eslint": "^8.68.0",
|
|
161
|
+
"vitest": "^4.1.11",
|
|
162
|
+
"zod": "^3.25.76"
|
|
158
163
|
},
|
|
159
164
|
"engines": {
|
|
160
165
|
"node": ">=18.0.0",
|
|
@@ -163,18 +168,23 @@
|
|
|
163
168
|
"overrides": {
|
|
164
169
|
"lodash": ">=4.17.21",
|
|
165
170
|
"lodash-es": ">=4.17.21",
|
|
166
|
-
"dompurify": "
|
|
171
|
+
"dompurify": "3.4.14",
|
|
167
172
|
"fast-xml-parser": ">=4.5.5",
|
|
168
173
|
"@xmldom/xmldom": ">=0.8.12",
|
|
169
174
|
"swiper": ">=12.1.2",
|
|
170
|
-
"brace-expansion": "1.1.
|
|
175
|
+
"brace-expansion": "1.1.18",
|
|
171
176
|
"follow-redirects": ">=1.15.12",
|
|
172
177
|
"smol-toml": ">=1.6.1",
|
|
173
178
|
"axios": ">=1.15.0",
|
|
174
179
|
"flatted": ">=3.4.1",
|
|
175
180
|
"yaml": ">=2.8.3",
|
|
176
|
-
"picomatch": "
|
|
181
|
+
"picomatch": "4.0.7",
|
|
177
182
|
"immutable": ">=3.8.3",
|
|
178
|
-
"minimatch": "3.1.
|
|
183
|
+
"minimatch": "3.1.4",
|
|
184
|
+
"nanoid": "3.3.18",
|
|
185
|
+
"postcss": "8.5.26",
|
|
186
|
+
"undici": "7.29.0",
|
|
187
|
+
"vite": "7.3.5",
|
|
188
|
+
"esbuild": "0.28.1"
|
|
179
189
|
}
|
|
180
190
|
}
|