@fruga/sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +118 -0
- package/connect/package.json +6 -0
- package/core/package.json +6 -0
- package/dist/connect.d.mts +73 -0
- package/dist/connect.d.ts +73 -0
- package/dist/connect.js +26 -0
- package/dist/connect.mjs +26 -0
- package/dist/core/package.json +5 -0
- package/dist/index.d.mts +398 -0
- package/dist/index.d.ts +398 -0
- package/dist/index.js +783 -0
- package/dist/index.mjs +725 -0
- package/dist/loader/package.json +17 -0
- package/dist/loader-react.d.mts +127 -0
- package/dist/loader-react.d.ts +127 -0
- package/dist/loader-react.js +26 -0
- package/dist/loader-react.mjs +26 -0
- package/dist/loader.d.mts +24 -0
- package/dist/loader.d.ts +24 -0
- package/dist/loader.js +2 -0
- package/dist/loader.mjs +2 -0
- package/dist/relay.css +3 -0
- package/dist/relay.d.mts +61 -0
- package/dist/relay.d.ts +61 -0
- package/dist/relay.js +2 -0
- package/dist/relay.mjs +2 -0
- package/loader/package.json +6 -0
- package/package.json +89 -0
- package/relay/package.json +6 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"main": "../loader.js",
|
|
3
|
+
"module": "../loader.mjs",
|
|
4
|
+
"types": "../loader.d.ts",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"import": "../loader.mjs",
|
|
8
|
+
"require": "../loader.js",
|
|
9
|
+
"types": "../loader.d.ts"
|
|
10
|
+
},
|
|
11
|
+
"./react": {
|
|
12
|
+
"import": "../loader-react.mjs",
|
|
13
|
+
"require": "../loader-react.js",
|
|
14
|
+
"types": "../loader-react.d.ts"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
interface LoaderOptions {
|
|
4
|
+
partnerKey: string;
|
|
5
|
+
containerId?: string;
|
|
6
|
+
token?: string;
|
|
7
|
+
onTokenRequired?: () => Promise<string>;
|
|
8
|
+
theme?: 'light' | 'dark';
|
|
9
|
+
primaryColor?: string;
|
|
10
|
+
appUrl?: string;
|
|
11
|
+
autoMount?: boolean;
|
|
12
|
+
userId?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const requestBalance: () => void;
|
|
17
|
+
declare const getBalance: () => Promise<{
|
|
18
|
+
available: number;
|
|
19
|
+
pending: number;
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
declare const DEFAULT_THEME: {
|
|
23
|
+
widgetTitle: string;
|
|
24
|
+
launcherLabel: string;
|
|
25
|
+
launcherIcon: "gift" | "sparkles" | "credit" | "arrow" | "none";
|
|
26
|
+
showLauncher: boolean;
|
|
27
|
+
mode: "dark" | "light";
|
|
28
|
+
allowUserThemeControl: boolean;
|
|
29
|
+
defaultTheme: "dark" | "light";
|
|
30
|
+
uiVersion: "legacy" | "current";
|
|
31
|
+
primary: string;
|
|
32
|
+
accent: string;
|
|
33
|
+
accentTextLight: string;
|
|
34
|
+
accentTextDark: string;
|
|
35
|
+
bg: string;
|
|
36
|
+
panel: string;
|
|
37
|
+
panel2: string;
|
|
38
|
+
itemBg: string;
|
|
39
|
+
text: string;
|
|
40
|
+
muted: string;
|
|
41
|
+
border: string;
|
|
42
|
+
success: string;
|
|
43
|
+
danger: string;
|
|
44
|
+
warning: string;
|
|
45
|
+
lightBg: string;
|
|
46
|
+
lightPanel: string;
|
|
47
|
+
lightPanel2: string;
|
|
48
|
+
lightItemBg: string;
|
|
49
|
+
lightText: string;
|
|
50
|
+
lightMuted: string;
|
|
51
|
+
lightBorder: string;
|
|
52
|
+
};
|
|
53
|
+
type Theme = typeof DEFAULT_THEME & {
|
|
54
|
+
textColorDark?: string;
|
|
55
|
+
textColorLight?: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
type PartnerType = 'RELAY' | 'CONNECT' | 'EXTERNAL_TENANT';
|
|
59
|
+
interface WidgetUiConfig {
|
|
60
|
+
accent: string;
|
|
61
|
+
defaultTheme: 'light' | 'dark';
|
|
62
|
+
launcherIcon: string;
|
|
63
|
+
showLauncher: boolean;
|
|
64
|
+
launcherLabel: string;
|
|
65
|
+
accentTextDark: string;
|
|
66
|
+
accentTextLight: string;
|
|
67
|
+
allowUserThemeControl: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface BootstrapAuth {
|
|
70
|
+
mode: string;
|
|
71
|
+
audience: string;
|
|
72
|
+
issuer: string;
|
|
73
|
+
tokenTtlSeconds: number;
|
|
74
|
+
}
|
|
75
|
+
interface WidgetBootstrap {
|
|
76
|
+
partnerEnvId: string;
|
|
77
|
+
partnerId: string;
|
|
78
|
+
partnerType: PartnerType;
|
|
79
|
+
partnerPayout: 'PARTNER' | 'USER';
|
|
80
|
+
auth: BootstrapAuth;
|
|
81
|
+
config: {
|
|
82
|
+
ui: WidgetUiConfig;
|
|
83
|
+
validValues: {
|
|
84
|
+
defaultTheme: string[];
|
|
85
|
+
launcherIcon: string[];
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface RelayConfig {
|
|
90
|
+
containerId: string;
|
|
91
|
+
partnerKey: string;
|
|
92
|
+
token?: string;
|
|
93
|
+
baseUrl?: string;
|
|
94
|
+
theme?: 'light' | 'dark';
|
|
95
|
+
primaryColor?: string;
|
|
96
|
+
userId?: string;
|
|
97
|
+
bootstrapConfig?: WidgetBootstrap;
|
|
98
|
+
isHostMobile?: boolean;
|
|
99
|
+
hostHeight?: number;
|
|
100
|
+
}
|
|
101
|
+
declare global {
|
|
102
|
+
interface Window {
|
|
103
|
+
FrugaRelay?: {
|
|
104
|
+
init: (config: RelayConfig) => void;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface WidgetContainerProps {
|
|
110
|
+
children: ReactNode;
|
|
111
|
+
hostHeight?: number;
|
|
112
|
+
isMobile?: boolean;
|
|
113
|
+
theme: Theme;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
declare const useFrugaWidget: (config: LoaderOptions) => {
|
|
117
|
+
mount: () => Promise<void>;
|
|
118
|
+
unmount: () => void;
|
|
119
|
+
};
|
|
120
|
+
declare const FrugaWidget: React.FC<LoaderOptions>;
|
|
121
|
+
/**
|
|
122
|
+
* A wrapper component that provides the WidgetProvider context around the WidgetContainer.
|
|
123
|
+
* This ensures that any child components or the container itself can access the WidgetContext.
|
|
124
|
+
*/
|
|
125
|
+
declare const WidgetUI: React.FC<WidgetContainerProps>;
|
|
126
|
+
|
|
127
|
+
export { FrugaWidget, WidgetUI, getBalance, requestBalance, useFrugaWidget };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
interface LoaderOptions {
|
|
4
|
+
partnerKey: string;
|
|
5
|
+
containerId?: string;
|
|
6
|
+
token?: string;
|
|
7
|
+
onTokenRequired?: () => Promise<string>;
|
|
8
|
+
theme?: 'light' | 'dark';
|
|
9
|
+
primaryColor?: string;
|
|
10
|
+
appUrl?: string;
|
|
11
|
+
autoMount?: boolean;
|
|
12
|
+
userId?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const requestBalance: () => void;
|
|
17
|
+
declare const getBalance: () => Promise<{
|
|
18
|
+
available: number;
|
|
19
|
+
pending: number;
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
declare const DEFAULT_THEME: {
|
|
23
|
+
widgetTitle: string;
|
|
24
|
+
launcherLabel: string;
|
|
25
|
+
launcherIcon: "gift" | "sparkles" | "credit" | "arrow" | "none";
|
|
26
|
+
showLauncher: boolean;
|
|
27
|
+
mode: "dark" | "light";
|
|
28
|
+
allowUserThemeControl: boolean;
|
|
29
|
+
defaultTheme: "dark" | "light";
|
|
30
|
+
uiVersion: "legacy" | "current";
|
|
31
|
+
primary: string;
|
|
32
|
+
accent: string;
|
|
33
|
+
accentTextLight: string;
|
|
34
|
+
accentTextDark: string;
|
|
35
|
+
bg: string;
|
|
36
|
+
panel: string;
|
|
37
|
+
panel2: string;
|
|
38
|
+
itemBg: string;
|
|
39
|
+
text: string;
|
|
40
|
+
muted: string;
|
|
41
|
+
border: string;
|
|
42
|
+
success: string;
|
|
43
|
+
danger: string;
|
|
44
|
+
warning: string;
|
|
45
|
+
lightBg: string;
|
|
46
|
+
lightPanel: string;
|
|
47
|
+
lightPanel2: string;
|
|
48
|
+
lightItemBg: string;
|
|
49
|
+
lightText: string;
|
|
50
|
+
lightMuted: string;
|
|
51
|
+
lightBorder: string;
|
|
52
|
+
};
|
|
53
|
+
type Theme = typeof DEFAULT_THEME & {
|
|
54
|
+
textColorDark?: string;
|
|
55
|
+
textColorLight?: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
type PartnerType = 'RELAY' | 'CONNECT' | 'EXTERNAL_TENANT';
|
|
59
|
+
interface WidgetUiConfig {
|
|
60
|
+
accent: string;
|
|
61
|
+
defaultTheme: 'light' | 'dark';
|
|
62
|
+
launcherIcon: string;
|
|
63
|
+
showLauncher: boolean;
|
|
64
|
+
launcherLabel: string;
|
|
65
|
+
accentTextDark: string;
|
|
66
|
+
accentTextLight: string;
|
|
67
|
+
allowUserThemeControl: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface BootstrapAuth {
|
|
70
|
+
mode: string;
|
|
71
|
+
audience: string;
|
|
72
|
+
issuer: string;
|
|
73
|
+
tokenTtlSeconds: number;
|
|
74
|
+
}
|
|
75
|
+
interface WidgetBootstrap {
|
|
76
|
+
partnerEnvId: string;
|
|
77
|
+
partnerId: string;
|
|
78
|
+
partnerType: PartnerType;
|
|
79
|
+
partnerPayout: 'PARTNER' | 'USER';
|
|
80
|
+
auth: BootstrapAuth;
|
|
81
|
+
config: {
|
|
82
|
+
ui: WidgetUiConfig;
|
|
83
|
+
validValues: {
|
|
84
|
+
defaultTheme: string[];
|
|
85
|
+
launcherIcon: string[];
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface RelayConfig {
|
|
90
|
+
containerId: string;
|
|
91
|
+
partnerKey: string;
|
|
92
|
+
token?: string;
|
|
93
|
+
baseUrl?: string;
|
|
94
|
+
theme?: 'light' | 'dark';
|
|
95
|
+
primaryColor?: string;
|
|
96
|
+
userId?: string;
|
|
97
|
+
bootstrapConfig?: WidgetBootstrap;
|
|
98
|
+
isHostMobile?: boolean;
|
|
99
|
+
hostHeight?: number;
|
|
100
|
+
}
|
|
101
|
+
declare global {
|
|
102
|
+
interface Window {
|
|
103
|
+
FrugaRelay?: {
|
|
104
|
+
init: (config: RelayConfig) => void;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface WidgetContainerProps {
|
|
110
|
+
children: ReactNode;
|
|
111
|
+
hostHeight?: number;
|
|
112
|
+
isMobile?: boolean;
|
|
113
|
+
theme: Theme;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
declare const useFrugaWidget: (config: LoaderOptions) => {
|
|
117
|
+
mount: () => Promise<void>;
|
|
118
|
+
unmount: () => void;
|
|
119
|
+
};
|
|
120
|
+
declare const FrugaWidget: React.FC<LoaderOptions>;
|
|
121
|
+
/**
|
|
122
|
+
* A wrapper component that provides the WidgetProvider context around the WidgetContainer.
|
|
123
|
+
* This ensures that any child components or the container itself can access the WidgetContext.
|
|
124
|
+
*/
|
|
125
|
+
declare const WidgetUI: React.FC<WidgetContainerProps>;
|
|
126
|
+
|
|
127
|
+
export { FrugaWidget, WidgetUI, getBalance, requestBalance, useFrugaWidget };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";var we=Object.create;var y=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var Fe=(a,e,t)=>e in a?y(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var ye=(a,e)=>{for(var t in e)y(a,t,{get:e[t],enumerable:!0})},ae=(a,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let u of Pe(e))!Be.call(a,u)&&u!==t&&y(a,u,{get:()=>e[u],enumerable:!(o=ke(e,u))||o.enumerable});return a};var Me=(a,e,t)=>(t=a!=null?we(Ae(a)):{},ae(e||!a||!a.__esModule?y(t,"default",{value:a,enumerable:!0}):t,a)),Te=a=>ae(y({},"__esModule",{value:!0}),a);var H=(a,e,t)=>Fe(a,typeof e!="symbol"?e+"":e,t);var Ze={};ye(Ze,{FrugaWidget:()=>Xe,WidgetUI:()=>Ke,getBalance:()=>Y,requestBalance:()=>j,useFrugaWidget:()=>ge});module.exports=Te(Ze);var O=require("react");var te={widgetTitle:"Savings Box",launcherLabel:"Insurance Savings",launcherIcon:"arrow",showLauncher:!0,mode:"light",allowUserThemeControl:!1,defaultTheme:"light",uiVersion:"current",primary:"#1E40AF",accent:"#2648C9",accentTextLight:"#FFFFFF",accentTextDark:"#FFFFFF",bg:"#0B1220",panel:"#0F1A2E",panel2:"#111F38",itemBg:"rgba(255,255,255,0.03)",text:"#E6EDF7",muted:"#A7B3C6",border:"rgba(255,255,255,0.08)",success:"#34D399",danger:"#EF4444",warning:"#FBBF24",lightBg:"#F8FAFC",lightPanel:"#FFFFFF",lightPanel2:"#F1F5F9",lightItemBg:"rgba(0,0,0,0.04)",lightText:"#0F172A",lightMuted:"#64748B",lightBorder:"rgba(0,0,0,0.1)"};function oe(a){let e=a.mode==="light",t=e?a.textColorLight?.trim()||a.lightText:a.textColorDark?.trim()||a.text;return{...a,bg:e?a.lightBg:a.bg,panel:e?a.lightPanel:a.panel,panel2:e?a.lightPanel2:a.panel2,itemBg:e?a.lightItemBg:a.itemBg,text:t,muted:e?a.lightMuted:a.muted,border:e?a.lightBorder:a.border,subtleBg:e?"rgba(0,0,0,0.02)":"rgba(255,255,255,0.03)",tooltipBg:e?"#FFFFFF":"#0B1220",tooltipBorder:e?"rgba(0,0,0,0.12)":"rgba(255,255,255,0.12)",accentText:e?a.accentTextLight?.trim()||"#0F172A":a.accentTextDark?.trim()||"#FFFFFF",isLight:e,mode:a.mode}}var Re=require("react/jsx-runtime");var g=require("react");var G=require("react");var E=(...a)=>a.filter((e,t,o)=>!!e&&e.trim()!==""&&o.indexOf(e)===t).join(" ").trim();var ue=a=>a.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var de=a=>a.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,o)=>o?o.toUpperCase():t.toLowerCase());var _=a=>{let e=de(a);return e.charAt(0).toUpperCase()+e.slice(1)};var M=require("react");var W={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var le=a=>{for(let e in a)if(e.startsWith("aria-")||e==="role"||e==="title")return!0;return!1};var B=require("react");var be=(0,B.createContext)({});var re=()=>(0,B.useContext)(be);var se=(0,M.forwardRef)(({color:a,size:e,strokeWidth:t,absoluteStrokeWidth:o,className:u="",children:d,iconNode:c,...s},i)=>{let{size:l=24,strokeWidth:r=2,absoluteStrokeWidth:I=!1,color:h="currentColor",className:p=""}=re()??{},f=o??I?Number(t??r)*24/Number(e??l):t??r;return(0,M.createElement)("svg",{ref:i,...W,width:e??l??W.width,height:e??l??W.height,stroke:a??h,strokeWidth:f,className:E("lucide",p,u),...!d&&!le(s)&&{"aria-hidden":"true"},...s},[...c.map(([w,x])=>(0,M.createElement)(w,x)),...Array.isArray(d)?d:[d]])});var C=(a,e)=>{let t=(0,G.forwardRef)(({className:o,...u},d)=>(0,G.createElement)(se,{ref:d,iconNode:e,className:E(`lucide-${ue(_(a))}`,`lucide-${a}`,o),...u}));return t.displayName=_(a),t};var qe=[["rect",{width:"20",height:"14",x:"2",y:"5",rx:"2",key:"ynyp8z"}],["line",{x1:"2",x2:"22",y1:"10",y2:"10",key:"1b3vmo"}]],T=C("credit-card",qe);var ve=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8",key:"1sqzm4"}],["path",{d:"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5",key:"kc0143"}],["rect",{x:"3",y:"7",width:"18",height:"4",rx:"1",key:"1hberx"}]],D=C("gift",ve);var Ue=[["path",{d:"M13 5H19V11",key:"1n1gyv"}],["path",{d:"M19 5L5 19",key:"72u4yj"}]],R=C("move-up-right",Ue);var Oe=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],S=C("sparkles",Oe);var He=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],b=C("x",He);var q=require("react/jsx-runtime");function fe({theme:a}){return a.launcherIcon==="none"?null:a.launcherIcon==="sparkles"?(0,q.jsx)(S,{size:20}):a.launcherIcon==="credit"?(0,q.jsx)(T,{size:20}):a.launcherIcon==="arrow"?(0,q.jsx)(R,{size:20}):(0,q.jsx)(D,{size:20})}var V=require("react");var ie=a=>{let e,t=new Set,o=(l,r)=>{let I=typeof l=="function"?l(e):l;if(!Object.is(I,e)){let h=e;e=r??(typeof I!="object"||I===null)?I:Object.assign({},e,I),t.forEach(p=>p(e,h))}},u=()=>e,s={setState:o,getState:u,getInitialState:()=>i,subscribe:l=>(t.add(l),()=>t.delete(l))},i=e=a(o,u,s);return s},ne=(a=>a?ie(a):ie);var v=Me(require("react"),1);var Ee=a=>a;function We(a,e=Ee){let t=v.default.useSyncExternalStore(a.subscribe,v.default.useCallback(()=>e(a.getState()),[a,e]),v.default.useCallback(()=>e(a.getInitialState()),[a,e]));return v.default.useDebugValue(t),t}var ce=a=>{let e=ne(a),t=o=>We(e,o);return Object.assign(t,e),t},pe=(a=>a?ce(a):ce);var P=pe(a=>({isOpen:!1,isFocused:!0,isIdle:!1,available:0,pending:0,mode:"light",token:null,partnerPayout:null,isAddingPayoutFromAlert:!1,showPayoutSuccess:!1,toggle:()=>a(e=>({isOpen:!e.isOpen})),setOpen:e=>a({isOpen:e}),setFocused:e=>a({isFocused:e}),setIdle:e=>a({isIdle:e}),setBalances:(e,t)=>a({available:e,pending:t}),setMode:e=>a({mode:e}),setToken:e=>a({token:e}),setPartnerPayout:e=>a({partnerPayout:e}),setIsAddingPayoutFromAlert:e=>a({isAddingPayoutFromAlert:e}),setShowPayoutSuccess:e=>a({showPayoutSuccess:e})}));function me(){let{setFocused:a,setIdle:e}=P(),t=(0,V.useRef)(null);(0,V.useEffect)(()=>{let o=()=>a(!0),u=()=>a(!1),d=()=>{e(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>{e(!0)},6e4)},c=()=>{d()};d(),a(document.hasFocus()),window.addEventListener("focus",o),window.addEventListener("blur",u);let s=["mousemove","keydown","scroll","touchstart","mousedown"];return s.forEach(i=>{window.addEventListener(i,c,i==="scroll"?!0:void 0)}),()=>{window.removeEventListener("focus",o),window.removeEventListener("blur",u),s.forEach(i=>{window.removeEventListener(i,c,i==="scroll"?!0:void 0)}),t.current&&clearTimeout(t.current)}},[a,e])}var L=require("react/jsx-runtime"),Le=({children:a,theme:e,hostHeight:t=800,isMobile:o=!1})=>{me();let{isOpen:u,toggle:d,mode:c}=P(),s=e||te,[i,l]=(0,g.useState)(t),[r,I]=(0,g.useState)(o),h=s.allowUserThemeControl?{...s,mode:c}:{...s,mode:s.mode||"light"},p=oe(h),f=(0,g.useRef)(null),w=(0,g.useRef)(null);return(0,g.useEffect)(()=>{let x=m=>{if(m.data?.type==="FRUGA_HOST_RESIZE"&&(l(m.data.hostHeight),I(m.data.isHostMobile)),m.data?.type==="FRUGA_TOKEN_UPDATE"){let{setToken:n}=P.getState();n(m.data.token)}if(m.data?.type==="FRUGA_GET_BALANCE"){let{available:n,pending:k}=P.getState();console.log("FRUGA_GET_BALANCE",n,k),window.parent.postMessage({type:"FRUGA_BALANCE_RESPONSE",requestId:m.data.requestId,available:n,pending:k},"*")}};return window.addEventListener("message",x),()=>window.removeEventListener("message",x)},[]),(0,g.useEffect)(()=>{if(!f.current)return;let x=()=>{if(!f.current)return;let n=u?450:100;!u&&w.current&&(n=w.current.offsetWidth+40);let k=u?Math.max(200,i-100):100;r&&u&&(n=window.innerWidth,k=i),window.parent.postMessage({type:"FRUGA_RESIZE",height:k,width:n,isFullscreen:r&&u},"*")},m=new ResizeObserver(()=>x());return m.observe(f.current),x(),()=>m.disconnect()},[u,i,r]),(0,L.jsxs)("div",{ref:f,className:p.mode==="dark"?"dark":"",style:{fontFamily:'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',color:p.text,display:"flex",flexDirection:"column",alignItems:"flex-end",justifyContent:"flex-end",padding:r&&u?"0":"20px",boxSizing:"border-box",height:"100%",margin:0,overscrollBehavior:"contain"},children:[u&&(0,L.jsx)("div",{style:{width:r?"100vw":"410px",minWidth:r?"100vw":"410px",flexShrink:0,maxHeight:r?"100vh":`${Math.max(100,i-100)}px`,height:"100%",marginBottom:r?"0":"20px",backgroundColor:p.accent,borderRadius:r?"0":"16px",boxShadow:r?"none":"0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0,0,0,0.1)",display:"flex",flexDirection:"column",overflow:"hidden",zIndex:9998},children:(0,L.jsx)("div",{className:"fruga-scrollbar",style:{flex:1,minHeight:0,backgroundColor:p.isLight?"#f9f9f9":"#111",display:"flex",flexDirection:"column",boxShadow:r?"none":"0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0,0,0,0.1)"},children:a})}),(0,L.jsxs)("button",{ref:w,onClick:d,style:{backgroundColor:p.accent,color:p.accentText,border:"none",cursor:"pointer",boxShadow:"0 12px 30px -5px rgba(0, 0, 0, 0.1), 0 0 1px rgba(0,0,0, 0.1)",display:u?"none":"flex",alignItems:"center",justifyContent:"center",zIndex:9999,flexShrink:0,borderRadius:"20px",padding:"10px 16px",transition:"transform 0.3s ease-in-out"},className:"flex h-15 items-center gap-2 rounded-xl px-4 active:scale-[0.99]","aria-label":u?"Close widget":"Open widget",children:[s.launcherLabel&&!u?(0,L.jsxs)(L.Fragment,{children:[s.launcherLabel!=="none"&&(0,L.jsx)("div",{className:"text-sm font-semibold",children:s.launcherLabel}),(0,L.jsx)("div",{className:"flex h-6 w-5 shrink-0 items-center justify-center",children:(0,L.jsx)(fe,{theme:p})})]}):null,u?(0,L.jsx)(b,{}):null]})]})};var Ie=require("react/jsx-runtime");var xe=require("react");var U={BOOTSTRAP_DATA:"fruga_bootstrap",BOOTSTRAP_CONFIG:"fruga_active_config"},A=class{static set(e,t){if(!(typeof window>"u"))try{window.localStorage.setItem(e,JSON.stringify(t))}catch(o){console.warn(`[FrugaStorage] Failed to save key "${e}":`,o)}}static get(e){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(e);return t?JSON.parse(t):null}catch(t){return console.warn(`[FrugaStorage] Failed to load key "${e}":`,t),null}}static remove(e){typeof window>"u"||window.localStorage.removeItem(e)}static clear(){typeof window>"u"||window.localStorage.clear()}};var Ve=typeof process<"u"&&process.env.VITE_FRUGA_API_URL||"https://api-dev.fruga.co.uk",Ce=a=>a||Ve;var Q={partnerEnvId:"env_dev_123",partnerId:"partner_abc_456",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"JWT",audience:"https://api.fruga.io",issuer:"https://auth.fruga.io",tokenTtlSeconds:70},config:{ui:{accent:"#F97316",defaultTheme:"light",launcherIcon:"arrow",showLauncher:!0,launcherLabel:"Help",accentTextDark:"#832424",accentTextLight:"#d81414",allowUserThemeControl:!0},validValues:{defaultTheme:["light","dark"],launcherIcon:["none","gift","sparkles","credit","arrow"]}}};var z=class{async bootstrap(e,t){let o=Ce(t);if(typeof process<"u"&&process.env.VITE_FRUGA_MODE==="test")return console.log("Fruga SDK: Using bootstrap mocks (VITE_FRUGA_MODE=test)"),Q;try{let d=await fetch(`${o}/widget/bootstrap?partnerKey=${e}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"}});if(!d.ok)throw new Error(`Bootstrap failed with status: ${d.status}`);return await d.json()}catch(d){return console.error("Fruga SDK: Bootstrap failed, falling back to mocks",d),Q}}};var N=class{mount(e,t,o){let{partnerKey:u,theme:d,primaryColor:c,appUrl:s,userId:i}=o,l=document.createElement("iframe"),r=t.partnerType==="EXTERNAL_TENANT"?"relay":"connect",I=typeof document<"u"?document.currentScript:null,h=I?.src||(typeof window<"u"?window.location.href:""),p=`./${r}/index.html`;if(!I)p=`https://frugainsurance.github.io/sdk/${r}/index.html`;else try{new URL(h).pathname.includes("/dist/")&&(p=`./${r}/index.html`)}catch{}let f=new URL(s||t.appUrl||p,h);f.searchParams.set("partnerKey",u),f.searchParams.set("partnerId",t.partnerId);let w=typeof window<"u"?window.innerWidth<768:!1;if(f.searchParams.set("isHostMobile",String(w)),typeof window<"u"&&(f.searchParams.set("hostHeight",String(window.innerHeight)),f.searchParams.set("hostWidth",String(window.innerWidth))),d&&f.searchParams.set("theme",d),c&&f.searchParams.set("primaryColor",c),i&&f.searchParams.set("userId",i),t.token&&f.searchParams.set("token",t.token),o.baseUrl&&f.searchParams.set("baseUrl",o.baseUrl),t.bootstrapConfig)try{let n=btoa(JSON.stringify(t.bootstrapConfig));f.searchParams.set("bootstrapConfig",n)}catch(n){console.warn("FrugaLoader: Failed to encode bootstrapConfig for iframe URL",n)}l.src=f.toString(),l.style.border="none",l.style.width="410px",l.style.height="600px",l.style.backgroundColor="transparent";let x=n=>{if(n.source===l.contentWindow&&n.data?.type==="FRUGA_RESIZE"){let{width:k,height:he,isFullscreen:Se}=n.data;Se?(l.style.position="fixed",l.style.inset="0",l.style.width="100vw",l.style.height="100vh",l.style.zIndex="99999"):(l.style.position="static",l.style.width=`${k}px`,l.style.height=`${he}px`,l.style.zIndex="auto")}},m=()=>{l.contentWindow?.postMessage({type:"FRUGA_HOST_RESIZE",isHostMobile:window.innerWidth<768,hostHeight:window.innerHeight,hostWidth:window.innerWidth},"*")};return window.addEventListener("message",x),window.addEventListener("resize",m),e.appendChild(l),{iframe:l,cleanup:()=>{window.removeEventListener("message",x),window.removeEventListener("resize",m)}}}unmount(e){e.remove()}};var X=class{constructor(e,t){this.bootstrapService=e;this.widgetMounter=t;H(this,"state",{container:null,iframe:null,options:null,currentToken:null});H(this,"pendingRequests",new Map);H(this,"handleIframeMessage",async e=>{if(!(this.state.iframe&&e.source!==this.state.iframe.contentWindow)){if(e.data?.type==="NEED_TOKEN"&&this.state.options?.onTokenRequired)try{let t=await this.state.options.onTokenRequired();this.state.currentToken=t,this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_TOKEN_UPDATE",token:t},"*")}catch(t){console.error("FrugaLoader: Failed to refresh token:",t)}if(e.data?.type==="FRUGA_BALANCE_RESPONSE"){let{requestId:t,available:o,pending:u}=e.data;if(t&&this.pendingRequests.has(t)){let{resolve:d,timeout:c}=this.pendingRequests.get(t);clearTimeout(c),this.pendingRequests.delete(t),d({available:o,pending:u})}}}})}async init(e){if(this.state.options=e,e.autoMount!==!1){if(e.token&&(this.state.currentToken=e.token),e.onTokenRequired)try{this.state.currentToken=await e.onTokenRequired()}catch(o){console.error("FrugaLoader: Failed to fetch initial token:",o)}await this.mount()}}setOptions(e){this.state.options=e}async mount(){if(!this.state.options||this.state.container&&this.state.iframe&&document.body.contains(this.state.container))return;let e=A.get(U.BOOTSTRAP_DATA);if(e)this.doMount(e);else{let t=A.get(U.BOOTSTRAP_CONFIG);if(t){let o={partnerEnvId:"cached",partnerId:"cached",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"none",audience:"",issuer:"",tokenTtlSeconds:0},config:t};this.doMount(o)}}try{let t=await this.bootstrapService.bootstrap(this.state.options.partnerKey,this.state.options.baseUrl);A.set(U.BOOTSTRAP_DATA,t),A.set(U.BOOTSTRAP_CONFIG,t.config),this.doMount(t)}catch{}}doMount(e){if(!this.state.options)return;let{containerId:t="fruga-widget-root"}=this.state.options,o=document.getElementById(t);o?o.innerHTML="":(o=document.createElement("div"),o.id=t,document.body.appendChild(o)),o.style.position="fixed",o.style.bottom="0px",o.style.right="0px",o.style.zIndex="9999";let d={...{...this.state.options,containerId:this.state.options.containerId||"fruga-widget-root",bootstrapConfig:e,token:this.state.currentToken||void 0},partnerId:e.partnerId,partnerType:e.partnerType},{iframe:c,cleanup:s}=this.widgetMounter.mount(o,d,this.state.options);this.state.container=o,this.state.iframe=c,o._frugaCleanup=s,window.addEventListener("message",this.handleIframeMessage)}unmount(){if(this.state.container&&document.body.contains(this.state.container)){let e=this.state.container._frugaCleanup;e?.(),this.widgetMounter.unmount(this.state.container)}this.state.container=null,this.state.iframe=null,window.removeEventListener("message",this.handleIframeMessage)}requestBalance(){this.state.iframe&&this.state.iframe.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE"},"*")}async getBalance(){if(!this.state.iframe)throw new Error("FrugaLoader: Cannot get balance - widget not mounted");let e=Math.random().toString(36).substring(2,15);return new Promise((t,o)=>{let u=setTimeout(()=>{this.pendingRequests.has(e)&&(this.pendingRequests.delete(e),o(new Error("FrugaLoader: Get balance request timed out")))},5e3);this.pendingRequests.set(e,{resolve:t,reject:o,timeout:u}),this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE",requestId:e},"*")})}};var ze=new z,Ne=new N,F=new X(ze,Ne),J=async()=>{await F.mount()},Z=()=>{F.unmount()},K=async a=>{await F.init(a)},$=a=>{F.setOptions(a)},j=()=>{F.requestBalance()},Y=async()=>F.getBalance();if(typeof window<"u"){let a=document.currentScript;if(a){let e=a.getAttribute("data-partner-key"),t=a.getAttribute("data-container-id")||void 0,o=a.getAttribute("data-app-url")||void 0,u=a.getAttribute("data-base-url")||void 0,d=window.frugaConfig||{};(e||d.partnerKey)&&K({partnerKey:e||d.partnerKey||"demo-key",containerId:t||d.containerId,appUrl:o||d.appUrl,baseUrl:u||d.baseUrl,theme:d.theme,primaryColor:d.primaryColor})}window.FrugaLoader={init:K,setOptions:$,mount:J,unmount:Z,requestBalance:j,getBalance:Y}}var ee=require("react/jsx-runtime");var ge=a=>{let e=(0,O.useRef)(!1);return(0,O.useEffect)(()=>{e.current&&$(a)},[a]),(0,O.useEffect)(()=>(e.current||K(a).then(()=>{e.current=!0}),()=>{Z(),e.current=!1}),[a.partnerKey,a.appUrl]),{mount:J,unmount:Z}},Xe=a=>{let e=a.containerId||"fruga-widget-container";return ge({...a,containerId:e,autoMount:!0}),(0,ee.jsx)("div",{id:e,style:{width:"100%",height:"100%"}})},Ke=({children:a,...e})=>(0,ee.jsx)(Le,{...e,children:a});0&&(module.exports={FrugaWidget,WidgetUI,getBalance,requestBalance,useFrugaWidget});
|
|
2
|
+
/*! Bundled license information:
|
|
3
|
+
|
|
4
|
+
lucide-react/dist/esm/shared/src/utils/mergeClasses.js:
|
|
5
|
+
lucide-react/dist/esm/shared/src/utils/toKebabCase.js:
|
|
6
|
+
lucide-react/dist/esm/shared/src/utils/toCamelCase.js:
|
|
7
|
+
lucide-react/dist/esm/shared/src/utils/toPascalCase.js:
|
|
8
|
+
lucide-react/dist/esm/defaultAttributes.js:
|
|
9
|
+
lucide-react/dist/esm/shared/src/utils/hasA11yProp.js:
|
|
10
|
+
lucide-react/dist/esm/context.js:
|
|
11
|
+
lucide-react/dist/esm/Icon.js:
|
|
12
|
+
lucide-react/dist/esm/createLucideIcon.js:
|
|
13
|
+
lucide-react/dist/esm/icons/credit-card.js:
|
|
14
|
+
lucide-react/dist/esm/icons/gift.js:
|
|
15
|
+
lucide-react/dist/esm/icons/move-up-right.js:
|
|
16
|
+
lucide-react/dist/esm/icons/sparkles.js:
|
|
17
|
+
lucide-react/dist/esm/icons/x.js:
|
|
18
|
+
lucide-react/dist/esm/lucide-react.js:
|
|
19
|
+
(**
|
|
20
|
+
* @license lucide-react v1.7.0 - ISC
|
|
21
|
+
*
|
|
22
|
+
* This source code is licensed under the ISC license.
|
|
23
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
24
|
+
*)
|
|
25
|
+
*/
|
|
26
|
+
//# sourceMappingURL=loader-react.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
var xe=Object.defineProperty;var Ce=(a,e,t)=>e in a?xe(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var D=(a,e,t)=>Ce(a,typeof e!="symbol"?e+"":e,t);import{useEffect as pe,useRef as We}from"react";var K={widgetTitle:"Savings Box",launcherLabel:"Insurance Savings",launcherIcon:"arrow",showLauncher:!0,mode:"light",allowUserThemeControl:!1,defaultTheme:"light",uiVersion:"current",primary:"#1E40AF",accent:"#2648C9",accentTextLight:"#FFFFFF",accentTextDark:"#FFFFFF",bg:"#0B1220",panel:"#0F1A2E",panel2:"#111F38",itemBg:"rgba(255,255,255,0.03)",text:"#E6EDF7",muted:"#A7B3C6",border:"rgba(255,255,255,0.08)",success:"#34D399",danger:"#EF4444",warning:"#FBBF24",lightBg:"#F8FAFC",lightPanel:"#FFFFFF",lightPanel2:"#F1F5F9",lightItemBg:"rgba(0,0,0,0.04)",lightText:"#0F172A",lightMuted:"#64748B",lightBorder:"rgba(0,0,0,0.1)"};function Z(a){let e=a.mode==="light",t=e?a.textColorLight?.trim()||a.lightText:a.textColorDark?.trim()||a.text;return{...a,bg:e?a.lightBg:a.bg,panel:e?a.lightPanel:a.panel,panel2:e?a.lightPanel2:a.panel2,itemBg:e?a.lightItemBg:a.itemBg,text:t,muted:e?a.lightMuted:a.muted,border:e?a.lightBorder:a.border,subtleBg:e?"rgba(0,0,0,0.02)":"rgba(255,255,255,0.03)",tooltipBg:e?"#FFFFFF":"#0B1220",tooltipBorder:e?"rgba(0,0,0,0.12)":"rgba(255,255,255,0.12)",accentText:e?a.accentTextLight?.trim()||"#0F172A":a.accentTextDark?.trim()||"#FFFFFF",isLight:e,mode:a.mode}}import{jsx as ra}from"react/jsx-runtime";import{useState as le,useEffect as re,useRef as se}from"react";import{forwardRef as Pe,createElement as Ae}from"react";var R=(...a)=>a.filter((e,t,o)=>!!e&&e.trim()!==""&&o.indexOf(e)===t).join(" ").trim();var _=a=>a.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var Q=a=>a.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,o)=>o?o.toUpperCase():t.toLowerCase());var G=a=>{let e=Q(a);return e.charAt(0).toUpperCase()+e.slice(1)};import{forwardRef as ke,createElement as j}from"react";var b={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var J=a=>{for(let e in a)if(e.startsWith("aria-")||e==="role"||e==="title")return!0;return!1};import{createContext as he,useContext as Se,useMemo as xa,createElement as Ca}from"react";var we=he({});var $=()=>Se(we);var Y=ke(({color:a,size:e,strokeWidth:t,absoluteStrokeWidth:o,className:d="",children:u,iconNode:c,...s},i)=>{let{size:l=24,strokeWidth:r=2,absoluteStrokeWidth:L=!1,color:C="currentColor",className:p=""}=$()??{},f=o??L?Number(t??r)*24/Number(e??l):t??r;return j("svg",{ref:i,...b,width:e??l??b.width,height:e??l??b.height,stroke:a??C,strokeWidth:f,className:R("lucide",p,d),...!u&&!J(s)&&{"aria-hidden":"true"},...s},[...c.map(([h,I])=>j(h,I)),...Array.isArray(u)?u:[u]])});var x=(a,e)=>{let t=Pe(({className:o,...d},u)=>Ae(Y,{ref:u,iconNode:e,className:R(`lucide-${_(G(a))}`,`lucide-${a}`,o),...d}));return t.displayName=G(a),t};var Be=[["rect",{width:"20",height:"14",x:"2",y:"5",rx:"2",key:"ynyp8z"}],["line",{x1:"2",x2:"22",y1:"10",y2:"10",key:"1b3vmo"}]],B=x("credit-card",Be);var Fe=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8",key:"1sqzm4"}],["path",{d:"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5",key:"kc0143"}],["rect",{x:"3",y:"7",width:"18",height:"4",rx:"1",key:"1hberx"}]],F=x("gift",Fe);var ye=[["path",{d:"M13 5H19V11",key:"1n1gyv"}],["path",{d:"M19 5L5 19",key:"72u4yj"}]],y=x("move-up-right",ye);var Me=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],g=x("sparkles",Me);var Te=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],M=x("x",Te);import{jsx as q}from"react/jsx-runtime";function ee({theme:a}){return a.launcherIcon==="none"?null:a.launcherIcon==="sparkles"?q(g,{size:20}):a.launcherIcon==="credit"?q(B,{size:20}):a.launcherIcon==="arrow"?q(y,{size:20}):q(F,{size:20})}import{useEffect as qe,useRef as ve}from"react";var ae=a=>{let e,t=new Set,o=(l,r)=>{let L=typeof l=="function"?l(e):l;if(!Object.is(L,e)){let C=e;e=r??(typeof L!="object"||L===null)?L:Object.assign({},e,L),t.forEach(p=>p(e,C))}},d=()=>e,s={setState:o,getState:d,getInitialState:()=>i,subscribe:l=>(t.add(l),()=>t.delete(l))},i=e=a(o,d,s);return s},te=(a=>a?ae(a):ae);import v from"react";var De=a=>a;function Re(a,e=De){let t=v.useSyncExternalStore(a.subscribe,v.useCallback(()=>e(a.getState()),[a,e]),v.useCallback(()=>e(a.getInitialState()),[a,e]));return v.useDebugValue(t),t}var oe=a=>{let e=te(a),t=o=>Re(e,o);return Object.assign(t,e),t},ue=(a=>a?oe(a):oe);var w=ue(a=>({isOpen:!1,isFocused:!0,isIdle:!1,available:0,pending:0,mode:"light",token:null,partnerPayout:null,isAddingPayoutFromAlert:!1,showPayoutSuccess:!1,toggle:()=>a(e=>({isOpen:!e.isOpen})),setOpen:e=>a({isOpen:e}),setFocused:e=>a({isFocused:e}),setIdle:e=>a({isIdle:e}),setBalances:(e,t)=>a({available:e,pending:t}),setMode:e=>a({mode:e}),setToken:e=>a({token:e}),setPartnerPayout:e=>a({partnerPayout:e}),setIsAddingPayoutFromAlert:e=>a({isAddingPayoutFromAlert:e}),setShowPayoutSuccess:e=>a({showPayoutSuccess:e})}));function de(){let{setFocused:a,setIdle:e}=w(),t=ve(null);qe(()=>{let o=()=>a(!0),d=()=>a(!1),u=()=>{e(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>{e(!0)},6e4)},c=()=>{u()};u(),a(document.hasFocus()),window.addEventListener("focus",o),window.addEventListener("blur",d);let s=["mousemove","keydown","scroll","touchstart","mousedown"];return s.forEach(i=>{window.addEventListener(i,c,i==="scroll"?!0:void 0)}),()=>{window.removeEventListener("focus",o),window.removeEventListener("blur",d),s.forEach(i=>{window.removeEventListener(i,c,i==="scroll"?!0:void 0)}),t.current&&clearTimeout(t.current)}},[a,e])}import{Fragment as Ue,jsx as P,jsxs as V}from"react/jsx-runtime";var fe=({children:a,theme:e,hostHeight:t=800,isMobile:o=!1})=>{de();let{isOpen:d,toggle:u,mode:c}=w(),s=e||K,[i,l]=le(t),[r,L]=le(o),C=s.allowUserThemeControl?{...s,mode:c}:{...s,mode:s.mode||"light"},p=Z(C),f=se(null),h=se(null);return re(()=>{let I=m=>{if(m.data?.type==="FRUGA_HOST_RESIZE"&&(l(m.data.hostHeight),L(m.data.isHostMobile)),m.data?.type==="FRUGA_TOKEN_UPDATE"){let{setToken:n}=w.getState();n(m.data.token)}if(m.data?.type==="FRUGA_GET_BALANCE"){let{available:n,pending:S}=w.getState();console.log("FRUGA_GET_BALANCE",n,S),window.parent.postMessage({type:"FRUGA_BALANCE_RESPONSE",requestId:m.data.requestId,available:n,pending:S},"*")}};return window.addEventListener("message",I),()=>window.removeEventListener("message",I)},[]),re(()=>{if(!f.current)return;let I=()=>{if(!f.current)return;let n=d?450:100;!d&&h.current&&(n=h.current.offsetWidth+40);let S=d?Math.max(200,i-100):100;r&&d&&(n=window.innerWidth,S=i),window.parent.postMessage({type:"FRUGA_RESIZE",height:S,width:n,isFullscreen:r&&d},"*")},m=new ResizeObserver(()=>I());return m.observe(f.current),I(),()=>m.disconnect()},[d,i,r]),V("div",{ref:f,className:p.mode==="dark"?"dark":"",style:{fontFamily:'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',color:p.text,display:"flex",flexDirection:"column",alignItems:"flex-end",justifyContent:"flex-end",padding:r&&d?"0":"20px",boxSizing:"border-box",height:"100%",margin:0,overscrollBehavior:"contain"},children:[d&&P("div",{style:{width:r?"100vw":"410px",minWidth:r?"100vw":"410px",flexShrink:0,maxHeight:r?"100vh":`${Math.max(100,i-100)}px`,height:"100%",marginBottom:r?"0":"20px",backgroundColor:p.accent,borderRadius:r?"0":"16px",boxShadow:r?"none":"0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0,0,0,0.1)",display:"flex",flexDirection:"column",overflow:"hidden",zIndex:9998},children:P("div",{className:"fruga-scrollbar",style:{flex:1,minHeight:0,backgroundColor:p.isLight?"#f9f9f9":"#111",display:"flex",flexDirection:"column",boxShadow:r?"none":"0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0,0,0,0.1)"},children:a})}),V("button",{ref:h,onClick:u,style:{backgroundColor:p.accent,color:p.accentText,border:"none",cursor:"pointer",boxShadow:"0 12px 30px -5px rgba(0, 0, 0, 0.1), 0 0 1px rgba(0,0,0, 0.1)",display:d?"none":"flex",alignItems:"center",justifyContent:"center",zIndex:9999,flexShrink:0,borderRadius:"20px",padding:"10px 16px",transition:"transform 0.3s ease-in-out"},className:"flex h-15 items-center gap-2 rounded-xl px-4 active:scale-[0.99]","aria-label":d?"Close widget":"Open widget",children:[s.launcherLabel&&!d?V(Ue,{children:[s.launcherLabel!=="none"&&P("div",{className:"text-sm font-semibold",children:s.launcherLabel}),P("div",{className:"flex h-6 w-5 shrink-0 items-center justify-center",children:P(ee,{theme:p})})]}):null,d?P(M,{}):null]})]})};import{Fragment as St,jsx as wt}from"react/jsx-runtime";import{useEffect as At,useState as Bt}from"react";var T={BOOTSTRAP_DATA:"fruga_bootstrap",BOOTSTRAP_CONFIG:"fruga_active_config"},k=class{static set(e,t){if(!(typeof window>"u"))try{window.localStorage.setItem(e,JSON.stringify(t))}catch(o){console.warn(`[FrugaStorage] Failed to save key "${e}":`,o)}}static get(e){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(e);return t?JSON.parse(t):null}catch(t){return console.warn(`[FrugaStorage] Failed to load key "${e}":`,t),null}}static remove(e){typeof window>"u"||window.localStorage.removeItem(e)}static clear(){typeof window>"u"||window.localStorage.clear()}};var Oe=typeof process<"u"&&process.env.VITE_FRUGA_API_URL||"https://api-dev.fruga.co.uk",ie=a=>a||Oe;var z={partnerEnvId:"env_dev_123",partnerId:"partner_abc_456",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"JWT",audience:"https://api.fruga.io",issuer:"https://auth.fruga.io",tokenTtlSeconds:70},config:{ui:{accent:"#F97316",defaultTheme:"light",launcherIcon:"arrow",showLauncher:!0,launcherLabel:"Help",accentTextDark:"#832424",accentTextLight:"#d81414",allowUserThemeControl:!0},validValues:{defaultTheme:["light","dark"],launcherIcon:["none","gift","sparkles","credit","arrow"]}}};var U=class{async bootstrap(e,t){let o=ie(t);if(typeof process<"u"&&process.env.VITE_FRUGA_MODE==="test")return console.log("Fruga SDK: Using bootstrap mocks (VITE_FRUGA_MODE=test)"),z;try{let u=await fetch(`${o}/widget/bootstrap?partnerKey=${e}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"}});if(!u.ok)throw new Error(`Bootstrap failed with status: ${u.status}`);return await u.json()}catch(u){return console.error("Fruga SDK: Bootstrap failed, falling back to mocks",u),z}}};var O=class{mount(e,t,o){let{partnerKey:d,theme:u,primaryColor:c,appUrl:s,userId:i}=o,l=document.createElement("iframe"),r=t.partnerType==="EXTERNAL_TENANT"?"relay":"connect",L=typeof document<"u"?document.currentScript:null,C=L?.src||(typeof window<"u"?window.location.href:""),p=`./${r}/index.html`;if(!L)p=`https://frugainsurance.github.io/sdk/${r}/index.html`;else try{new URL(C).pathname.includes("/dist/")&&(p=`./${r}/index.html`)}catch{}let f=new URL(s||t.appUrl||p,C);f.searchParams.set("partnerKey",d),f.searchParams.set("partnerId",t.partnerId);let h=typeof window<"u"?window.innerWidth<768:!1;if(f.searchParams.set("isHostMobile",String(h)),typeof window<"u"&&(f.searchParams.set("hostHeight",String(window.innerHeight)),f.searchParams.set("hostWidth",String(window.innerWidth))),u&&f.searchParams.set("theme",u),c&&f.searchParams.set("primaryColor",c),i&&f.searchParams.set("userId",i),t.token&&f.searchParams.set("token",t.token),o.baseUrl&&f.searchParams.set("baseUrl",o.baseUrl),t.bootstrapConfig)try{let n=btoa(JSON.stringify(t.bootstrapConfig));f.searchParams.set("bootstrapConfig",n)}catch(n){console.warn("FrugaLoader: Failed to encode bootstrapConfig for iframe URL",n)}l.src=f.toString(),l.style.border="none",l.style.width="410px",l.style.height="600px",l.style.backgroundColor="transparent";let I=n=>{if(n.source===l.contentWindow&&n.data?.type==="FRUGA_RESIZE"){let{width:S,height:Le,isFullscreen:Ie}=n.data;Ie?(l.style.position="fixed",l.style.inset="0",l.style.width="100vw",l.style.height="100vh",l.style.zIndex="99999"):(l.style.position="static",l.style.width=`${S}px`,l.style.height=`${Le}px`,l.style.zIndex="auto")}},m=()=>{l.contentWindow?.postMessage({type:"FRUGA_HOST_RESIZE",isHostMobile:window.innerWidth<768,hostHeight:window.innerHeight,hostWidth:window.innerWidth},"*")};return window.addEventListener("message",I),window.addEventListener("resize",m),e.appendChild(l),{iframe:l,cleanup:()=>{window.removeEventListener("message",I),window.removeEventListener("resize",m)}}}unmount(e){e.remove()}};var H=class{constructor(e,t){this.bootstrapService=e;this.widgetMounter=t;D(this,"state",{container:null,iframe:null,options:null,currentToken:null});D(this,"pendingRequests",new Map);D(this,"handleIframeMessage",async e=>{if(!(this.state.iframe&&e.source!==this.state.iframe.contentWindow)){if(e.data?.type==="NEED_TOKEN"&&this.state.options?.onTokenRequired)try{let t=await this.state.options.onTokenRequired();this.state.currentToken=t,this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_TOKEN_UPDATE",token:t},"*")}catch(t){console.error("FrugaLoader: Failed to refresh token:",t)}if(e.data?.type==="FRUGA_BALANCE_RESPONSE"){let{requestId:t,available:o,pending:d}=e.data;if(t&&this.pendingRequests.has(t)){let{resolve:u,timeout:c}=this.pendingRequests.get(t);clearTimeout(c),this.pendingRequests.delete(t),u({available:o,pending:d})}}}})}async init(e){if(this.state.options=e,e.autoMount!==!1){if(e.token&&(this.state.currentToken=e.token),e.onTokenRequired)try{this.state.currentToken=await e.onTokenRequired()}catch(o){console.error("FrugaLoader: Failed to fetch initial token:",o)}await this.mount()}}setOptions(e){this.state.options=e}async mount(){if(!this.state.options||this.state.container&&this.state.iframe&&document.body.contains(this.state.container))return;let e=k.get(T.BOOTSTRAP_DATA);if(e)this.doMount(e);else{let t=k.get(T.BOOTSTRAP_CONFIG);if(t){let o={partnerEnvId:"cached",partnerId:"cached",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"none",audience:"",issuer:"",tokenTtlSeconds:0},config:t};this.doMount(o)}}try{let t=await this.bootstrapService.bootstrap(this.state.options.partnerKey,this.state.options.baseUrl);k.set(T.BOOTSTRAP_DATA,t),k.set(T.BOOTSTRAP_CONFIG,t.config),this.doMount(t)}catch{}}doMount(e){if(!this.state.options)return;let{containerId:t="fruga-widget-root"}=this.state.options,o=document.getElementById(t);o?o.innerHTML="":(o=document.createElement("div"),o.id=t,document.body.appendChild(o)),o.style.position="fixed",o.style.bottom="0px",o.style.right="0px",o.style.zIndex="9999";let u={...{...this.state.options,containerId:this.state.options.containerId||"fruga-widget-root",bootstrapConfig:e,token:this.state.currentToken||void 0},partnerId:e.partnerId,partnerType:e.partnerType},{iframe:c,cleanup:s}=this.widgetMounter.mount(o,u,this.state.options);this.state.container=o,this.state.iframe=c,o._frugaCleanup=s,window.addEventListener("message",this.handleIframeMessage)}unmount(){if(this.state.container&&document.body.contains(this.state.container)){let e=this.state.container._frugaCleanup;e?.(),this.widgetMounter.unmount(this.state.container)}this.state.container=null,this.state.iframe=null,window.removeEventListener("message",this.handleIframeMessage)}requestBalance(){this.state.iframe&&this.state.iframe.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE"},"*")}async getBalance(){if(!this.state.iframe)throw new Error("FrugaLoader: Cannot get balance - widget not mounted");let e=Math.random().toString(36).substring(2,15);return new Promise((t,o)=>{let d=setTimeout(()=>{this.pendingRequests.has(e)&&(this.pendingRequests.delete(e),o(new Error("FrugaLoader: Get balance request timed out")))},5e3);this.pendingRequests.set(e,{resolve:t,reject:o,timeout:d}),this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE",requestId:e},"*")})}};var He=new U,Ee=new O,A=new H(He,Ee),N=async()=>{await A.mount()},W=()=>{A.unmount()},E=async a=>{await A.init(a)},X=a=>{A.setOptions(a)},ne=()=>{A.requestBalance()},ce=async()=>A.getBalance();if(typeof window<"u"){let a=document.currentScript;if(a){let e=a.getAttribute("data-partner-key"),t=a.getAttribute("data-container-id")||void 0,o=a.getAttribute("data-app-url")||void 0,d=a.getAttribute("data-base-url")||void 0,u=window.frugaConfig||{};(e||u.partnerKey)&&E({partnerKey:e||u.partnerKey||"demo-key",containerId:t||u.containerId,appUrl:o||u.appUrl,baseUrl:d||u.baseUrl,theme:u.theme,primaryColor:u.primaryColor})}window.FrugaLoader={init:E,setOptions:X,mount:N,unmount:W,requestBalance:ne,getBalance:ce}}import{jsx as me}from"react/jsx-runtime";var Ge=a=>{let e=We(!1);return pe(()=>{e.current&&X(a)},[a]),pe(()=>(e.current||E(a).then(()=>{e.current=!0}),()=>{W(),e.current=!1}),[a.partnerKey,a.appUrl]),{mount:N,unmount:W}},Lo=a=>{let e=a.containerId||"fruga-widget-container";return Ge({...a,containerId:e,autoMount:!0}),me("div",{id:e,style:{width:"100%",height:"100%"}})},Io=({children:a,...e})=>me(fe,{...e,children:a});export{Lo as FrugaWidget,Io as WidgetUI,ce as getBalance,ne as requestBalance,Ge as useFrugaWidget};
|
|
2
|
+
/*! Bundled license information:
|
|
3
|
+
|
|
4
|
+
lucide-react/dist/esm/shared/src/utils/mergeClasses.js:
|
|
5
|
+
lucide-react/dist/esm/shared/src/utils/toKebabCase.js:
|
|
6
|
+
lucide-react/dist/esm/shared/src/utils/toCamelCase.js:
|
|
7
|
+
lucide-react/dist/esm/shared/src/utils/toPascalCase.js:
|
|
8
|
+
lucide-react/dist/esm/defaultAttributes.js:
|
|
9
|
+
lucide-react/dist/esm/shared/src/utils/hasA11yProp.js:
|
|
10
|
+
lucide-react/dist/esm/context.js:
|
|
11
|
+
lucide-react/dist/esm/Icon.js:
|
|
12
|
+
lucide-react/dist/esm/createLucideIcon.js:
|
|
13
|
+
lucide-react/dist/esm/icons/credit-card.js:
|
|
14
|
+
lucide-react/dist/esm/icons/gift.js:
|
|
15
|
+
lucide-react/dist/esm/icons/move-up-right.js:
|
|
16
|
+
lucide-react/dist/esm/icons/sparkles.js:
|
|
17
|
+
lucide-react/dist/esm/icons/x.js:
|
|
18
|
+
lucide-react/dist/esm/lucide-react.js:
|
|
19
|
+
(**
|
|
20
|
+
* @license lucide-react v1.7.0 - ISC
|
|
21
|
+
*
|
|
22
|
+
* This source code is licensed under the ISC license.
|
|
23
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
24
|
+
*)
|
|
25
|
+
*/
|
|
26
|
+
//# sourceMappingURL=loader-react.mjs.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface LoaderOptions {
|
|
2
|
+
partnerKey: string;
|
|
3
|
+
containerId?: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
onTokenRequired?: () => Promise<string>;
|
|
6
|
+
theme?: 'light' | 'dark';
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
appUrl?: string;
|
|
9
|
+
autoMount?: boolean;
|
|
10
|
+
userId?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const mount: () => Promise<void>;
|
|
15
|
+
declare const unmount: () => void;
|
|
16
|
+
declare const init: (options: LoaderOptions) => Promise<void>;
|
|
17
|
+
declare const setOptions: (options: LoaderOptions) => void;
|
|
18
|
+
declare const requestBalance: () => void;
|
|
19
|
+
declare const getBalance: () => Promise<{
|
|
20
|
+
available: number;
|
|
21
|
+
pending: number;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export { type LoaderOptions, getBalance, init, mount, requestBalance, setOptions, unmount };
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface LoaderOptions {
|
|
2
|
+
partnerKey: string;
|
|
3
|
+
containerId?: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
onTokenRequired?: () => Promise<string>;
|
|
6
|
+
theme?: 'light' | 'dark';
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
appUrl?: string;
|
|
9
|
+
autoMount?: boolean;
|
|
10
|
+
userId?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const mount: () => Promise<void>;
|
|
15
|
+
declare const unmount: () => void;
|
|
16
|
+
declare const init: (options: LoaderOptions) => Promise<void>;
|
|
17
|
+
declare const setOptions: (options: LoaderOptions) => void;
|
|
18
|
+
declare const requestBalance: () => void;
|
|
19
|
+
declare const getBalance: () => Promise<{
|
|
20
|
+
available: number;
|
|
21
|
+
pending: number;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export { type LoaderOptions, getBalance, init, mount, requestBalance, setOptions, unmount };
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var Y=Object.create;var h=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=(r,e,t)=>e in r?h(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var re=(r,e)=>{for(var t in e)h(r,t,{get:e[t],enumerable:!0})},L=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of X(e))!ee.call(r,i)&&i!==t&&h(r,i,{get:()=>e[i],enumerable:!(o=J(e,i))||o.enumerable});return r};var oe=(r,e,t)=>(t=r!=null?Y(Z(r)):{},L(e||!r||!r.__esModule?h(t,"default",{value:r,enumerable:!0}):t,r)),ne=r=>L(h({},"__esModule",{value:!0}),r);var x=(r,e,t)=>te(r,typeof e!="symbol"?e+"":e,t);var ge={};re(ge,{getBalance:()=>K,init:()=>P,mount:()=>H,requestBalance:()=>z,setOptions:()=>G,unmount:()=>$});module.exports=ne(ge);var ie=require("react/jsx-runtime");var A=require("react");var se=require("react/jsx-runtime");var U=require("react");var C=r=>{let e,t=new Set,o=(n,g)=>{let d=typeof n=="function"?n(e):n;if(!Object.is(d,e)){let T=e;e=g??(typeof d!="object"||d===null)?d:Object.assign({},e,d),t.forEach(f=>f(e,T))}},i=()=>e,u={setState:o,getState:i,getInitialState:()=>b,subscribe:n=>(t.add(n),()=>t.delete(n))},b=e=r(o,i,u);return u},M=(r=>r?C(r):C);var y=oe(require("react"),1);var ce=r=>r;function de(r,e=ce){let t=y.default.useSyncExternalStore(r.subscribe,y.default.useCallback(()=>e(r.getState()),[r,e]),y.default.useCallback(()=>e(r.getInitialState()),[r,e]));return y.default.useDebugValue(t),t}var O=r=>{let e=M(r),t=o=>de(e,o);return Object.assign(t,e),t},D=(r=>r?O(r):O);var S=D(r=>({isOpen:!1,isFocused:!0,isIdle:!1,available:0,pending:0,mode:"light",token:null,partnerPayout:null,isAddingPayoutFromAlert:!1,showPayoutSuccess:!1,toggle:()=>r(e=>({isOpen:!e.isOpen})),setOpen:e=>r({isOpen:e}),setFocused:e=>r({isFocused:e}),setIdle:e=>r({isIdle:e}),setBalances:(e,t)=>r({available:e,pending:t}),setMode:e=>r({mode:e}),setToken:e=>r({token:e}),setPartnerPayout:e=>r({partnerPayout:e}),setIsAddingPayoutFromAlert:e=>r({isAddingPayoutFromAlert:e}),setShowPayoutSuccess:e=>r({showPayoutSuccess:e})}));var F=require("react/jsx-runtime");var _=require("react/jsx-runtime");var W=require("react");var w={BOOTSTRAP_DATA:"fruga_bootstrap",BOOTSTRAP_CONFIG:"fruga_active_config"},p=class{static set(e,t){if(!(typeof window>"u"))try{window.localStorage.setItem(e,JSON.stringify(t))}catch(o){console.warn(`[FrugaStorage] Failed to save key "${e}":`,o)}}static get(e){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(e);return t?JSON.parse(t):null}catch(t){return console.warn(`[FrugaStorage] Failed to load key "${e}":`,t),null}}static remove(e){typeof window>"u"||window.localStorage.removeItem(e)}static clear(){typeof window>"u"||window.localStorage.clear()}};var le=typeof process<"u"&&process.env.VITE_FRUGA_API_URL||"https://api-dev.fruga.co.uk",N=r=>r||le;var I={partnerEnvId:"env_dev_123",partnerId:"partner_abc_456",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"JWT",audience:"https://api.fruga.io",issuer:"https://auth.fruga.io",tokenTtlSeconds:70},config:{ui:{accent:"#F97316",defaultTheme:"light",launcherIcon:"arrow",showLauncher:!0,launcherLabel:"Help",accentTextDark:"#832424",accentTextLight:"#d81414",allowUserThemeControl:!0},validValues:{defaultTheme:["light","dark"],launcherIcon:["none","gift","sparkles","credit","arrow"]}}};var v=class{async bootstrap(e,t){let o=N(t);if(typeof process<"u"&&process.env.VITE_FRUGA_MODE==="test")return console.log("Fruga SDK: Using bootstrap mocks (VITE_FRUGA_MODE=test)"),I;try{let a=await fetch(`${o}/widget/bootstrap?partnerKey=${e}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"}});if(!a.ok)throw new Error(`Bootstrap failed with status: ${a.status}`);return await a.json()}catch(a){return console.error("Fruga SDK: Bootstrap failed, falling back to mocks",a),I}}};var E=class{mount(e,t,o){let{partnerKey:i,theme:a,primaryColor:c,appUrl:u,userId:b}=o,n=document.createElement("iframe"),g=t.partnerType==="EXTERNAL_TENANT"?"relay":"connect",d=typeof document<"u"?document.currentScript:null,T=d?.src||(typeof window<"u"?window.location.href:""),f=`./${g}/index.html`;if(!d)f=`https://frugainsurance.github.io/sdk/${g}/index.html`;else try{new URL(T).pathname.includes("/dist/")&&(f=`./${g}/index.html`)}catch{}let s=new URL(u||t.appUrl||f,T);s.searchParams.set("partnerKey",i),s.searchParams.set("partnerId",t.partnerId);let j=typeof window<"u"?window.innerWidth<768:!1;if(s.searchParams.set("isHostMobile",String(j)),typeof window<"u"&&(s.searchParams.set("hostHeight",String(window.innerHeight)),s.searchParams.set("hostWidth",String(window.innerWidth))),a&&s.searchParams.set("theme",a),c&&s.searchParams.set("primaryColor",c),b&&s.searchParams.set("userId",b),t.token&&s.searchParams.set("token",t.token),o.baseUrl&&s.searchParams.set("baseUrl",o.baseUrl),t.bootstrapConfig)try{let l=btoa(JSON.stringify(t.bootstrapConfig));s.searchParams.set("bootstrapConfig",l)}catch(l){console.warn("FrugaLoader: Failed to encode bootstrapConfig for iframe URL",l)}n.src=s.toString(),n.style.border="none",n.style.width="410px",n.style.height="600px",n.style.backgroundColor="transparent";let k=l=>{if(l.source===n.contentWindow&&l.data?.type==="FRUGA_RESIZE"){let{width:q,height:V,isFullscreen:Q}=l.data;Q?(n.style.position="fixed",n.style.inset="0",n.style.width="100vw",n.style.height="100vh",n.style.zIndex="99999"):(n.style.position="static",n.style.width=`${q}px`,n.style.height=`${V}px`,n.style.zIndex="auto")}},B=()=>{n.contentWindow?.postMessage({type:"FRUGA_HOST_RESIZE",isHostMobile:window.innerWidth<768,hostHeight:window.innerHeight,hostWidth:window.innerWidth},"*")};return window.addEventListener("message",k),window.addEventListener("resize",B),e.appendChild(n),{iframe:n,cleanup:()=>{window.removeEventListener("message",k),window.removeEventListener("resize",B)}}}unmount(e){e.remove()}};var R=class{constructor(e,t){this.bootstrapService=e;this.widgetMounter=t;x(this,"state",{container:null,iframe:null,options:null,currentToken:null});x(this,"pendingRequests",new Map);x(this,"handleIframeMessage",async e=>{if(!(this.state.iframe&&e.source!==this.state.iframe.contentWindow)){if(e.data?.type==="NEED_TOKEN"&&this.state.options?.onTokenRequired)try{let t=await this.state.options.onTokenRequired();this.state.currentToken=t,this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_TOKEN_UPDATE",token:t},"*")}catch(t){console.error("FrugaLoader: Failed to refresh token:",t)}if(e.data?.type==="FRUGA_BALANCE_RESPONSE"){let{requestId:t,available:o,pending:i}=e.data;if(t&&this.pendingRequests.has(t)){let{resolve:a,timeout:c}=this.pendingRequests.get(t);clearTimeout(c),this.pendingRequests.delete(t),a({available:o,pending:i})}}}})}async init(e){if(this.state.options=e,e.autoMount!==!1){if(e.token&&(this.state.currentToken=e.token),e.onTokenRequired)try{this.state.currentToken=await e.onTokenRequired()}catch(o){console.error("FrugaLoader: Failed to fetch initial token:",o)}await this.mount()}}setOptions(e){this.state.options=e}async mount(){if(!this.state.options||this.state.container&&this.state.iframe&&document.body.contains(this.state.container))return;let e=p.get(w.BOOTSTRAP_DATA);if(e)this.doMount(e);else{let t=p.get(w.BOOTSTRAP_CONFIG);if(t){let o={partnerEnvId:"cached",partnerId:"cached",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"none",audience:"",issuer:"",tokenTtlSeconds:0},config:t};this.doMount(o)}}try{let t=await this.bootstrapService.bootstrap(this.state.options.partnerKey,this.state.options.baseUrl);p.set(w.BOOTSTRAP_DATA,t),p.set(w.BOOTSTRAP_CONFIG,t.config),this.doMount(t)}catch{}}doMount(e){if(!this.state.options)return;let{containerId:t="fruga-widget-root"}=this.state.options,o=document.getElementById(t);o?o.innerHTML="":(o=document.createElement("div"),o.id=t,document.body.appendChild(o)),o.style.position="fixed",o.style.bottom="0px",o.style.right="0px",o.style.zIndex="9999";let a={...{...this.state.options,containerId:this.state.options.containerId||"fruga-widget-root",bootstrapConfig:e,token:this.state.currentToken||void 0},partnerId:e.partnerId,partnerType:e.partnerType},{iframe:c,cleanup:u}=this.widgetMounter.mount(o,a,this.state.options);this.state.container=o,this.state.iframe=c,o._frugaCleanup=u,window.addEventListener("message",this.handleIframeMessage)}unmount(){if(this.state.container&&document.body.contains(this.state.container)){let e=this.state.container._frugaCleanup;e?.(),this.widgetMounter.unmount(this.state.container)}this.state.container=null,this.state.iframe=null,window.removeEventListener("message",this.handleIframeMessage)}requestBalance(){this.state.iframe&&this.state.iframe.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE"},"*")}async getBalance(){if(!this.state.iframe)throw new Error("FrugaLoader: Cannot get balance - widget not mounted");let e=Math.random().toString(36).substring(2,15);return new Promise((t,o)=>{let i=setTimeout(()=>{this.pendingRequests.has(e)&&(this.pendingRequests.delete(e),o(new Error("FrugaLoader: Get balance request timed out")))},5e3);this.pendingRequests.set(e,{resolve:t,reject:o,timeout:i}),this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE",requestId:e},"*")})}};var pe=new v,ue=new E,m=new R(pe,ue),H=async()=>{await m.mount()},$=()=>{m.unmount()},P=async r=>{await m.init(r)},G=r=>{m.setOptions(r)},z=()=>{m.requestBalance()},K=async()=>m.getBalance();if(typeof window<"u"){let r=document.currentScript;if(r){let e=r.getAttribute("data-partner-key"),t=r.getAttribute("data-container-id")||void 0,o=r.getAttribute("data-app-url")||void 0,i=r.getAttribute("data-base-url")||void 0,a=window.frugaConfig||{};(e||a.partnerKey)&&P({partnerKey:e||a.partnerKey||"demo-key",containerId:t||a.containerId,appUrl:o||a.appUrl,baseUrl:i||a.baseUrl,theme:a.theme,primaryColor:a.primaryColor})}window.FrugaLoader={init:P,setOptions:G,mount:H,unmount:$,requestBalance:z,getBalance:K}}0&&(module.exports={getBalance,init,mount,requestBalance,setOptions,unmount});
|
|
2
|
+
//# sourceMappingURL=loader.js.map
|
package/dist/loader.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var _=Object.defineProperty;var W=(r,e,t)=>e in r?_(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var b=(r,e,t)=>W(r,typeof e!="symbol"?e+"":e,t);import{jsx as he}from"react/jsx-runtime";import{useState as $e,useEffect as Ge,useRef as ze}from"react";import{jsx as be}from"react/jsx-runtime";import{useEffect as ke,useRef as Be}from"react";var I=r=>{let e,t=new Set,o=(n,g)=>{let d=typeof n=="function"?n(e):n;if(!Object.is(d,e)){let w=e;e=g??(typeof d!="object"||d===null)?d:Object.assign({},e,d),t.forEach(f=>f(e,w))}},i=()=>e,u={setState:o,getState:i,getInitialState:()=>y,subscribe:n=>(t.add(n),()=>t.delete(n))},y=e=r(o,i,u);return u},P=(r=>r?I(r):I);import T from"react";var H=r=>r;function $(r,e=H){let t=T.useSyncExternalStore(r.subscribe,T.useCallback(()=>e(r.getState()),[r,e]),T.useCallback(()=>e(r.getInitialState()),[r,e]));return T.useDebugValue(t),t}var k=r=>{let e=P(r),t=o=>$(e,o);return Object.assign(t,e),t},B=(r=>r?k(r):k);var R=B(r=>({isOpen:!1,isFocused:!0,isIdle:!1,available:0,pending:0,mode:"light",token:null,partnerPayout:null,isAddingPayoutFromAlert:!1,showPayoutSuccess:!1,toggle:()=>r(e=>({isOpen:!e.isOpen})),setOpen:e=>r({isOpen:e}),setFocused:e=>r({isFocused:e}),setIdle:e=>r({isIdle:e}),setBalances:(e,t)=>r({available:e,pending:t}),setMode:e=>r({mode:e}),setToken:e=>r({token:e}),setPartnerPayout:e=>r({partnerPayout:e}),setIsAddingPayoutFromAlert:e=>r({isAddingPayoutFromAlert:e}),setShowPayoutSuccess:e=>r({showPayoutSuccess:e})}));import{Fragment as Xe,jsx as Je,jsxs as Ze}from"react/jsx-runtime";import{Fragment as ot,jsx as nt}from"react/jsx-runtime";import{useEffect as st,useState as ct}from"react";var h={BOOTSTRAP_DATA:"fruga_bootstrap",BOOTSTRAP_CONFIG:"fruga_active_config"},p=class{static set(e,t){if(!(typeof window>"u"))try{window.localStorage.setItem(e,JSON.stringify(t))}catch(o){console.warn(`[FrugaStorage] Failed to save key "${e}":`,o)}}static get(e){if(typeof window>"u")return null;try{let t=window.localStorage.getItem(e);return t?JSON.parse(t):null}catch(t){return console.warn(`[FrugaStorage] Failed to load key "${e}":`,t),null}}static remove(e){typeof window>"u"||window.localStorage.removeItem(e)}static clear(){typeof window>"u"||window.localStorage.clear()}};var G=typeof process<"u"&&process.env.VITE_FRUGA_API_URL||"https://api-dev.fruga.co.uk",L=r=>r||G;var S={partnerEnvId:"env_dev_123",partnerId:"partner_abc_456",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"JWT",audience:"https://api.fruga.io",issuer:"https://auth.fruga.io",tokenTtlSeconds:70},config:{ui:{accent:"#F97316",defaultTheme:"light",launcherIcon:"arrow",showLauncher:!0,launcherLabel:"Help",accentTextDark:"#832424",accentTextLight:"#d81414",allowUserThemeControl:!0},validValues:{defaultTheme:["light","dark"],launcherIcon:["none","gift","sparkles","credit","arrow"]}}};var x=class{async bootstrap(e,t){let o=L(t);if(typeof process<"u"&&process.env.VITE_FRUGA_MODE==="test")return console.log("Fruga SDK: Using bootstrap mocks (VITE_FRUGA_MODE=test)"),S;try{let a=await fetch(`${o}/widget/bootstrap?partnerKey=${e}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"}});if(!a.ok)throw new Error(`Bootstrap failed with status: ${a.status}`);return await a.json()}catch(a){return console.error("Fruga SDK: Bootstrap failed, falling back to mocks",a),S}}};var v=class{mount(e,t,o){let{partnerKey:i,theme:a,primaryColor:c,appUrl:u,userId:y}=o,n=document.createElement("iframe"),g=t.partnerType==="EXTERNAL_TENANT"?"relay":"connect",d=typeof document<"u"?document.currentScript:null,w=d?.src||(typeof window<"u"?window.location.href:""),f=`./${g}/index.html`;if(!d)f=`https://frugainsurance.github.io/sdk/${g}/index.html`;else try{new URL(w).pathname.includes("/dist/")&&(f=`./${g}/index.html`)}catch{}let s=new URL(u||t.appUrl||f,w);s.searchParams.set("partnerKey",i),s.searchParams.set("partnerId",t.partnerId);let M=typeof window<"u"?window.innerWidth<768:!1;if(s.searchParams.set("isHostMobile",String(M)),typeof window<"u"&&(s.searchParams.set("hostHeight",String(window.innerHeight)),s.searchParams.set("hostWidth",String(window.innerWidth))),a&&s.searchParams.set("theme",a),c&&s.searchParams.set("primaryColor",c),y&&s.searchParams.set("userId",y),t.token&&s.searchParams.set("token",t.token),o.baseUrl&&s.searchParams.set("baseUrl",o.baseUrl),t.bootstrapConfig)try{let l=btoa(JSON.stringify(t.bootstrapConfig));s.searchParams.set("bootstrapConfig",l)}catch(l){console.warn("FrugaLoader: Failed to encode bootstrapConfig for iframe URL",l)}n.src=s.toString(),n.style.border="none",n.style.width="410px",n.style.height="600px",n.style.backgroundColor="transparent";let A=l=>{if(l.source===n.contentWindow&&l.data?.type==="FRUGA_RESIZE"){let{width:O,height:D,isFullscreen:U}=l.data;U?(n.style.position="fixed",n.style.inset="0",n.style.width="100vw",n.style.height="100vh",n.style.zIndex="99999"):(n.style.position="static",n.style.width=`${O}px`,n.style.height=`${D}px`,n.style.zIndex="auto")}},F=()=>{n.contentWindow?.postMessage({type:"FRUGA_HOST_RESIZE",isHostMobile:window.innerWidth<768,hostHeight:window.innerHeight,hostWidth:window.innerWidth},"*")};return window.addEventListener("message",A),window.addEventListener("resize",F),e.appendChild(n),{iframe:n,cleanup:()=>{window.removeEventListener("message",A),window.removeEventListener("resize",F)}}}unmount(e){e.remove()}};var E=class{constructor(e,t){this.bootstrapService=e;this.widgetMounter=t;b(this,"state",{container:null,iframe:null,options:null,currentToken:null});b(this,"pendingRequests",new Map);b(this,"handleIframeMessage",async e=>{if(!(this.state.iframe&&e.source!==this.state.iframe.contentWindow)){if(e.data?.type==="NEED_TOKEN"&&this.state.options?.onTokenRequired)try{let t=await this.state.options.onTokenRequired();this.state.currentToken=t,this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_TOKEN_UPDATE",token:t},"*")}catch(t){console.error("FrugaLoader: Failed to refresh token:",t)}if(e.data?.type==="FRUGA_BALANCE_RESPONSE"){let{requestId:t,available:o,pending:i}=e.data;if(t&&this.pendingRequests.has(t)){let{resolve:a,timeout:c}=this.pendingRequests.get(t);clearTimeout(c),this.pendingRequests.delete(t),a({available:o,pending:i})}}}})}async init(e){if(this.state.options=e,e.autoMount!==!1){if(e.token&&(this.state.currentToken=e.token),e.onTokenRequired)try{this.state.currentToken=await e.onTokenRequired()}catch(o){console.error("FrugaLoader: Failed to fetch initial token:",o)}await this.mount()}}setOptions(e){this.state.options=e}async mount(){if(!this.state.options||this.state.container&&this.state.iframe&&document.body.contains(this.state.container))return;let e=p.get(h.BOOTSTRAP_DATA);if(e)this.doMount(e);else{let t=p.get(h.BOOTSTRAP_CONFIG);if(t){let o={partnerEnvId:"cached",partnerId:"cached",partnerType:"EXTERNAL_TENANT",partnerPayout:"USER",auth:{mode:"none",audience:"",issuer:"",tokenTtlSeconds:0},config:t};this.doMount(o)}}try{let t=await this.bootstrapService.bootstrap(this.state.options.partnerKey,this.state.options.baseUrl);p.set(h.BOOTSTRAP_DATA,t),p.set(h.BOOTSTRAP_CONFIG,t.config),this.doMount(t)}catch{}}doMount(e){if(!this.state.options)return;let{containerId:t="fruga-widget-root"}=this.state.options,o=document.getElementById(t);o?o.innerHTML="":(o=document.createElement("div"),o.id=t,document.body.appendChild(o)),o.style.position="fixed",o.style.bottom="0px",o.style.right="0px",o.style.zIndex="9999";let a={...{...this.state.options,containerId:this.state.options.containerId||"fruga-widget-root",bootstrapConfig:e,token:this.state.currentToken||void 0},partnerId:e.partnerId,partnerType:e.partnerType},{iframe:c,cleanup:u}=this.widgetMounter.mount(o,a,this.state.options);this.state.container=o,this.state.iframe=c,o._frugaCleanup=u,window.addEventListener("message",this.handleIframeMessage)}unmount(){if(this.state.container&&document.body.contains(this.state.container)){let e=this.state.container._frugaCleanup;e?.(),this.widgetMounter.unmount(this.state.container)}this.state.container=null,this.state.iframe=null,window.removeEventListener("message",this.handleIframeMessage)}requestBalance(){this.state.iframe&&this.state.iframe.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE"},"*")}async getBalance(){if(!this.state.iframe)throw new Error("FrugaLoader: Cannot get balance - widget not mounted");let e=Math.random().toString(36).substring(2,15);return new Promise((t,o)=>{let i=setTimeout(()=>{this.pendingRequests.has(e)&&(this.pendingRequests.delete(e),o(new Error("FrugaLoader: Get balance request timed out")))},5e3);this.pendingRequests.set(e,{resolve:t,reject:o,timeout:i}),this.state.iframe?.contentWindow?.postMessage({type:"FRUGA_GET_BALANCE",requestId:e},"*")})}};var z=new x,K=new v,m=new E(z,K),j=async()=>{await m.mount()},q=()=>{m.unmount()},C=async r=>{await m.init(r)},V=r=>{m.setOptions(r)},Q=()=>{m.requestBalance()},Y=async()=>m.getBalance();if(typeof window<"u"){let r=document.currentScript;if(r){let e=r.getAttribute("data-partner-key"),t=r.getAttribute("data-container-id")||void 0,o=r.getAttribute("data-app-url")||void 0,i=r.getAttribute("data-base-url")||void 0,a=window.frugaConfig||{};(e||a.partnerKey)&&C({partnerKey:e||a.partnerKey||"demo-key",containerId:t||a.containerId,appUrl:o||a.appUrl,baseUrl:i||a.baseUrl,theme:a.theme,primaryColor:a.primaryColor})}window.FrugaLoader={init:C,setOptions:V,mount:j,unmount:q,requestBalance:Q,getBalance:Y}}export{Y as getBalance,C as init,j as mount,Q as requestBalance,V as setOptions,q as unmount};
|
|
2
|
+
//# sourceMappingURL=loader.mjs.map
|