@benji-money/connect-sdk 1.1.4-beta.10 → 1.1.4-beta.11

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 CHANGED
@@ -101,7 +101,8 @@ The SDK accepts the following configuration options:
101
101
  - `onError` (optional): Callback function called when error occurs in the connect flow
102
102
  - `onExit` (optional): Callback function called when the user exits the connect flow
103
103
  - `onEvent` (optional): Callback function for handling various events
104
- - `onLoginReady` (optional): Embedded LOGIN button only — Benji Connect rendered the button, so the host can drop its skeleton
104
+ - `onLoginDisplayed` (optional): Embedded LOGIN button only — Connect painted themed chrome (first visual handoff); prefer this for dropping the host skeleton/cover. Requires Benji Connect [BEN-2572] to emit `LOGIN_DISPLAYED`; do not rely on this callback until Connect is deployed.
105
+ - `onLoginReady` (optional, deprecated for cover handoff): Embedded LOGIN button only — Connect resolved the auth link and rendered the button (session-ready). Prefer `onLoginDisplayed` for skeleton/cover removal.
105
106
  - `onLoginHover` (optional): Embedded LOGIN button only — pointer or focus entered the in-iframe button, for a host-owned tooltip
106
107
  - `onLoginClicked` (optional): Embedded LOGIN button only — the button was pressed, before the tab opens, for a host-owned pending state
107
108
  - `anchor` (optional): Live anchor binding — `HTMLElement`, CSS selector, getter `() => HTMLElement | null`, or ref `{ value: HTMLElement | null }`. Re-resolved on every layout pass. Falls back to centered when missing or invalid. See [Placement](#placement)
@@ -181,7 +182,7 @@ const sdk = new ConnectSDK({
181
182
  partnerAuthLink: connectUrl, // from Auth Service connect_url
182
183
  configToken: configToken, // from GET /connect/token — OAuth state
183
184
  },
184
- onLoginReady: () => { /* hide your skeleton */ },
185
+ onLoginDisplayed: () => { /* hide your skeleton */ },
185
186
  onLoginHover: () => { /* show your tooltip */ },
186
187
  onLoginClicked: () => { /* show your pending state */ },
187
188
  onSuccess: (token) => { /* ... */ },
@@ -110,7 +110,7 @@ var ConnectSDK = (() => {
110
110
  // src/utils/config.ts
111
111
  var buildContext = () => ({
112
112
  namespace: "benji-connect-sdk" ? "benji-connect-sdk" : "benji-connect-sdk",
113
- version: "1.1.4-beta.10" ? String("1.1.4-beta.10") : "0.0.0"
113
+ version: "1.1.4-beta.11" ? String("1.1.4-beta.11") : "0.0.0"
114
114
  });
115
115
  function isBenjiConnectEnvironment(environment) {
116
116
  return environment === "local" /* LOCAL */ || environment === "development" /* DEVELOPMENT */ || environment === "sandbox" /* SANDBOX */ || environment === "production" /* PRODUCTION */;
@@ -458,6 +458,7 @@ var ConnectSDK = (() => {
458
458
  BenjiConnectEventType2["EVENT"] = "EVENT";
459
459
  BenjiConnectEventType2["ERROR"] = "ERROR";
460
460
  BenjiConnectEventType2["LOGIN_READY"] = "LOGIN_READY";
461
+ BenjiConnectEventType2["LOGIN_DISPLAYED"] = "LOGIN_DISPLAYED";
461
462
  BenjiConnectEventType2["LOGIN_HOVER"] = "LOGIN_HOVER";
462
463
  BenjiConnectEventType2["LOGIN_CLICKED"] = "LOGIN_CLICKED";
463
464
  return BenjiConnectEventType2;
@@ -590,6 +591,7 @@ var ConnectSDK = (() => {
590
591
  ["ERROR" /* ERROR */]: mapToOnErrorData,
591
592
  ["EVENT" /* EVENT */]: mapToOnEventData,
592
593
  ["LOGIN_READY" /* LOGIN_READY */]: mapToLoginButtonEventData,
594
+ ["LOGIN_DISPLAYED" /* LOGIN_DISPLAYED */]: mapToLoginButtonEventData,
593
595
  ["LOGIN_HOVER" /* LOGIN_HOVER */]: mapToLoginButtonEventData,
594
596
  ["LOGIN_CLICKED" /* LOGIN_CLICKED */]: mapToLoginButtonEventData
595
597
  };
@@ -675,7 +677,7 @@ var ConnectSDK = (() => {
675
677
  return event.source === iframeWindow;
676
678
  }
677
679
  handleMessage(event) {
678
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
680
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D;
679
681
  if (!isConnectMessageType(event.data)) return;
680
682
  const expectedOrigin = new URL(Endpoints.benji_connect_auth_url).origin;
681
683
  if (!event || event.origin !== expectedOrigin) {
@@ -732,18 +734,25 @@ var ConnectSDK = (() => {
732
734
  (_r = (_q = this.config).onEvent) == null ? void 0 : _r.call(_q, callbackData.type, callbackData.metadata);
733
735
  break;
734
736
  }
737
+ case "LOGIN_DISPLAYED" /* LOGIN_DISPLAYED */: {
738
+ const connectMessage = message;
739
+ const callbackData = BenjiConnectCallbackMapperMap.LOGIN_DISPLAYED(connectMessage, connectMessage.data);
740
+ (_t = (_s = this.config).onLoginDisplayed) == null ? void 0 : _t.call(_s);
741
+ (_v = (_u = this.config).onEvent) == null ? void 0 : _v.call(_u, callbackData.type, callbackData.metadata);
742
+ break;
743
+ }
735
744
  case "LOGIN_HOVER" /* LOGIN_HOVER */: {
736
745
  const connectMessage = message;
737
746
  const callbackData = BenjiConnectCallbackMapperMap.LOGIN_HOVER(connectMessage, connectMessage.data);
738
- (_t = (_s = this.config).onLoginHover) == null ? void 0 : _t.call(_s);
739
- (_v = (_u = this.config).onEvent) == null ? void 0 : _v.call(_u, callbackData.type, callbackData.metadata);
747
+ (_x = (_w = this.config).onLoginHover) == null ? void 0 : _x.call(_w);
748
+ (_z = (_y = this.config).onEvent) == null ? void 0 : _z.call(_y, callbackData.type, callbackData.metadata);
740
749
  break;
741
750
  }
742
751
  case "LOGIN_CLICKED" /* LOGIN_CLICKED */: {
743
752
  const connectMessage = message;
744
753
  const callbackData = BenjiConnectCallbackMapperMap.LOGIN_CLICKED(connectMessage, connectMessage.data);
745
- (_x = (_w = this.config).onLoginClicked) == null ? void 0 : _x.call(_w);
746
- (_z = (_y = this.config).onEvent) == null ? void 0 : _z.call(_y, callbackData.type, callbackData.metadata);
754
+ (_B = (_A = this.config).onLoginClicked) == null ? void 0 : _B.call(_A);
755
+ (_D = (_C = this.config).onEvent) == null ? void 0 : _D.call(_C, callbackData.type, callbackData.metadata);
747
756
  break;
748
757
  }
749
758
  default: {
@@ -812,26 +821,33 @@ var ConnectSDK = (() => {
812
821
  if (this.isClosing || !this.iframe) return;
813
822
  this.postHostConfig();
814
823
  };
824
+ var _a;
815
825
  this.sdkConfig = config;
816
826
  if (!this.sdkConfig.environment) throw new Error("Environment is required");
817
- if (!this.sdkConfig.token) throw new Error("Connect token is required");
818
827
  const environment = mapToConnectEnvironment(this.sdkConfig.environment);
819
828
  this.sdkConfig.environment = environment;
820
829
  configureConfig(environment);
830
+ const connectToken = (_a = this.sdkConfig.token) == null ? void 0 : _a.trim();
831
+ if (!connectToken && !this.isEmbeddedButton()) {
832
+ throw new Error("Connect token is required");
833
+ }
821
834
  }
822
835
  postHostConfig() {
823
- var _a, _b, _c, _d;
836
+ var _a, _b, _c, _d, _e, _f, _g;
824
837
  if (!this.iframe) return;
825
838
  const login_button_theme = toWireLoginButtonTheme(
826
839
  (_a = this.sdkConfig.login) == null ? void 0 : _a.buttonTheme
827
840
  );
828
841
  const login_button_text = (_b = this.sdkConfig.login) == null ? void 0 : _b.buttonText;
842
+ const connectToken = (_c = this.sdkConfig.token) == null ? void 0 : _c.trim();
843
+ const configToken = (_e = (_d = this.sdkConfig.tokenData) == null ? void 0 : _d.configToken) == null ? void 0 : _e.trim();
844
+ const partnerAuthLink = (_g = (_f = this.sdkConfig.tokenData) == null ? void 0 : _f.partnerAuthLink) == null ? void 0 : _g.trim();
829
845
  this.router.postToConnect({
830
846
  type: "HOST_CONFIG_UPDATE" /* HOST_CONFIG_UPDATE */,
831
847
  data: {
832
- connect_token: this.sdkConfig.token,
833
- config_token: (_c = this.sdkConfig.tokenData) == null ? void 0 : _c.configToken,
834
- partner_auth_link: (_d = this.sdkConfig.tokenData) == null ? void 0 : _d.partnerAuthLink,
848
+ ...connectToken ? { connect_token: connectToken } : {},
849
+ ...configToken ? { config_token: configToken } : {},
850
+ ...partnerAuthLink ? { partner_auth_link: partnerAuthLink } : {},
835
851
  ...login_button_theme ? { login_button_theme } : {},
836
852
  ...login_button_text !== void 0 ? { login_button_text: login_button_text.trim() } : {}
837
853
  }
@@ -869,6 +885,7 @@ var ConnectSDK = (() => {
869
885
  onError: this.sdkConfig.onError,
870
886
  onExit: this.sdkConfig.onExit,
871
887
  onEvent: this.sdkConfig.onEvent,
888
+ onLoginDisplayed: this.sdkConfig.onLoginDisplayed,
872
889
  onLoginReady: this.sdkConfig.onLoginReady,
873
890
  onLoginHover: this.sdkConfig.onLoginHover,
874
891
  onLoginClicked: this.sdkConfig.onLoginClicked,
@@ -918,13 +935,16 @@ var ConnectSDK = (() => {
918
935
  });
919
936
  }
920
937
  buildIframeUrl() {
921
- var _a, _b, _c;
938
+ var _a, _b, _c, _d;
922
939
  const embedded = this.isEmbeddedButton();
923
940
  const url = new URL(
924
941
  embedded ? LOGIN_BUTTON_PATH : "",
925
942
  Endpoints.benji_connect_auth_url
926
943
  );
927
- url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.connectToken, this.sdkConfig.token);
944
+ const connectToken = (_a = this.sdkConfig.token) == null ? void 0 : _a.trim();
945
+ if (connectToken) {
946
+ url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.connectToken, connectToken);
947
+ }
928
948
  url.searchParams.set("t", String(Date.now()));
929
949
  if (this.sdkConfig.mode != null) {
930
950
  url.searchParams.set("mode", String(this.sdkConfig.mode));
@@ -934,11 +954,11 @@ var ConnectSDK = (() => {
934
954
  LOGIN_BUTTON_QUERY_KEYS.windowTarget,
935
955
  this.resolveLoginWindowTarget()
936
956
  );
937
- const buttonText = (_b = (_a = this.sdkConfig.login) == null ? void 0 : _a.buttonText) == null ? void 0 : _b.trim();
957
+ const buttonText = (_c = (_b = this.sdkConfig.login) == null ? void 0 : _b.buttonText) == null ? void 0 : _c.trim();
938
958
  if (buttonText) {
939
959
  url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.buttonText, buttonText);
940
960
  }
941
- const { configToken, partnerAuthLink } = (_c = this.sdkConfig.tokenData) != null ? _c : {};
961
+ const { configToken, partnerAuthLink } = (_d = this.sdkConfig.tokenData) != null ? _d : {};
942
962
  if (configToken) {
943
963
  url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.configToken, configToken);
944
964
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/production.ts","../src/config/sandbox.ts","../src/config/development.ts","../src/config/local.defaults.ts","../src/utils/environment.ts","../src/config/index.ts","../src/utils/config.ts","../src/utils/loginSurface.ts","../src/utils/placement.ts","../src/constants/login.ts","../src/types/event.ts","../src/utils/auth.ts","../src/utils/user.ts","../src/utils/transaction.ts","../src/types/router.ts","../src/router/message.ts","../src/utils/loginButtonTheme.ts","../src/connect-sdk.ts","../src/global.ts"],"sourcesContent":["export const project_environment: string = 'production';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url':'https://verifyapp.withbenji.com',\n 'benji_connect_auth_service_url' : 'https://authservice.withbenji.com'\n}","export const project_environment: string = 'sandbox';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url':'https://verifyapp-staging.withbenji.com',\n 'benji_connect_auth_service_url' : 'https://authservice-staging.withbenji.com'\n}","export const project_environment: string = 'development';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url': 'https://verifyapp-dev.withbenji.com',\n 'benji_connect_auth_service_url': 'https://authservice-dev.withbenji.com',\n};","/**\n * Build-time fallback when gitignored `local.ts` is absent (CI, fresh clones).\n * Same endpoints as development — not machine-specific localhost overrides.\n * Copy to `local.ts` locally for localhost URLs; see RELEASE.md.\n */\nexport const project_environment: string = 'local';\n\nexport const endpoints: Record<string, string> = {\n benji_connect_auth_url: 'https://verifyapp-dev.withbenji.com',\n benji_connect_auth_service_url: 'https://authservice-dev.withbenji.com',\n};\n","/** Hostnames that browsers use for loopback when typed literally in the URL bar. */\nexport const LOCAL_HOSTNAMES = ['localhost', '127.0.0.1', '::1', '[::1]'] as const;\n\nconst LOCAL_HOSTNAME_SET: ReadonlySet<string> = new Set(LOCAL_HOSTNAMES);\n\nexport function isLocalHost(\n hostname: string = typeof window !== 'undefined' ? window.location.hostname : ''\n): boolean {\n if (LOCAL_HOSTNAME_SET.has(hostname)) {\n return true;\n }\n // IPv4 loopback block 127.0.0.0/8 — covers 127.0.0.1 without listing every address\n if (hostname.startsWith('127.')) {\n return true;\n }\n return false;\n}\n","import * as productionConfig from './production';\nimport * as sandboxConfig from './sandbox';\nimport * as developmentConfig from './development';\nimport * as localConfig from './local';\nimport { BenjiConnectEnvironment } from '../types/config';\nimport { isLocalHost } from '../utils/environment';\n\nexport type EnvironmentConfigModule = {\n project_environment: string;\n endpoints: Record<string, string>;\n};\n\nconst env = typeof process !== 'undefined' ? process.env : {};\nlet data: EnvironmentConfigModule = developmentConfig;\ntype EndpointConfig = typeof developmentConfig.endpoints;\nexport let Endpoints: EndpointConfig = getEndpoints();\nexport let Environment = BenjiConnectEnvironment.DEVELOPMENT;\n\nexport function configureConfig(environment: BenjiConnectEnvironment) {\n if (environment == 'production') {\n console.log('[Connect SDK] configuring with environment production');\n data = productionConfig;\n } else if (environment == 'sandbox') {\n console.log('[Connect SDK] configuring with environment sandbox');\n data = sandboxConfig;\n } else if (environment == 'development') {\n console.log('[Connect SDK] configuring with environment development');\n data = developmentConfig;\n } else if (environment == 'local') {\n if (isLocalHost()) {\n console.log('[Connect SDK] configuring with environment local');\n data = localConfig;\n } else {\n console.log(\n '[Connect SDK] local environment requested on non-local host; using development'\n );\n data = developmentConfig;\n }\n }\n Endpoints = getEndpoints();\n Environment = getEnvironment();\n}\n\nfunction getEndpoints(): EndpointConfig {\n const entries = Object.entries(data.endpoints).map(([key, value]) => {\n const override = env?.[key] || value;\n return [key, override] as const;\n });\n return Object.fromEntries(entries) as EndpointConfig;\n}\n\nfunction getEnvironment(): BenjiConnectEnvironment {\n return data['project_environment'] as BenjiConnectEnvironment;\n}\n\nexport const Namespace = __NAMESPACE__;\nexport const Version = __VERSION__;\n","import { BenjiConnectEnvironment } from \"../types/config\";\nimport { isLocalHost } from \"./environment\";\n\nexport const buildContext = () => ({\n namespace: typeof __NAMESPACE__ !== 'undefined' && __NAMESPACE__ ? __NAMESPACE__ : 'benji-connect-sdk',\n version: typeof __VERSION__ !== 'undefined' && __VERSION__ ? String(__VERSION__) : '0.0.0',\n});\n\nexport function isBenjiConnectEnvironment(\n environment: unknown\n): environment is BenjiConnectEnvironment {\n return (\n environment === BenjiConnectEnvironment.LOCAL ||\n environment === BenjiConnectEnvironment.DEVELOPMENT ||\n environment === BenjiConnectEnvironment.SANDBOX ||\n environment === BenjiConnectEnvironment.PRODUCTION\n );\n}\n\nexport function mapToConnectEnvironment(\n environment: BenjiConnectEnvironment | string\n): BenjiConnectEnvironment {\n\n if (isBenjiConnectEnvironment(environment)) return environment;\n\n const environments: Record<string, BenjiConnectEnvironment> = {\n local: BenjiConnectEnvironment.LOCAL,\n development: BenjiConnectEnvironment.DEVELOPMENT,\n sandbox: BenjiConnectEnvironment.SANDBOX,\n production: BenjiConnectEnvironment.PRODUCTION,\n };\n const mapped = environments[environment];\n if (mapped) return mapped;\n\n const defaultEnvironment = isLocalHost()\n ? BenjiConnectEnvironment.LOCAL\n : BenjiConnectEnvironment.DEVELOPMENT;\n console.warn(`[Benji Connect SDK] ${environment} not valid environment defaulting to ${defaultEnvironment}`);\n\n return defaultEnvironment;\n}","import {\n BenjiConnectLoginSurface,\n BenjiConnectMode,\n PartnerIntegrationType,\n} from '../types/config';\n\n/**\n * True for the partner-auth LOGIN flows: mode 5 with a real integration type.\n * DUMMY has no partner window, so it keeps the modal surface.\n */\nexport function isNonDummyLogin(\n mode: BenjiConnectMode | undefined,\n authType: PartnerIntegrationType | undefined,\n): boolean {\n return (\n mode === BenjiConnectMode.LOGIN &&\n authType != null &&\n authType !== PartnerIntegrationType.DUMMY\n );\n}\n\n/**\n * Non-DUMMY LOGIN embeds Connect's own button so the click lands in Connect's\n * document; everything else renders the modal overlay. An explicit\n * `login.surface` wins, which is the escape hatch for partners still on the\n * modal.\n */\nexport function resolveLoginSurface(args: {\n mode: BenjiConnectMode | undefined;\n authType: PartnerIntegrationType | undefined;\n configured: BenjiConnectLoginSurface | undefined;\n}): BenjiConnectLoginSurface {\n if (args.configured) return args.configured;\n return isNonDummyLogin(args.mode, args.authType)\n ? BenjiConnectLoginSurface.EMBEDDED_BUTTON\n : BenjiConnectLoginSurface.MODAL;\n}\n\n/** Resolves `login.container` from an element or a document selector. */\nexport function resolveLoginContainer(\n container: HTMLElement | string | undefined,\n): HTMLElement | null {\n if (!container) return null;\n if (typeof container !== 'string') return container;\n try {\n return document.querySelector<HTMLElement>(container);\n } catch {\n console.warn('[Connect SDK] Invalid login.container selector', container);\n return null;\n }\n}\n","/**\n * Anchor-based iframe placement and host DOM application. Naming follows Floating UI /\n * Popper conventions (`bottom-end`, `bottom-start`). Computes layout rects, applies styles\n * to overlay/iframe elements, and manages reposition listeners.\n * @see https://floating-ui.com/docs/computePosition#placement\n */\n\nimport {\n BenjiConnectPlacement,\n type BenjiConnectAnchor,\n type BenjiConnectConfig,\n type BenjiConnectPlacementOffset,\n} from '../types/config';\n\nexport const IFRAME_WIDTH = 400;\nexport const IFRAME_HEIGHT = 645;\n\nconst IFRAME_STATIC_STYLE: CSSStyleDeclaration = {\n border: 'none',\n borderRadius: '20px',\n overflow: 'hidden',\n} as CSSStyleDeclaration;\n\nconst CONTAINER_BASE_STYLE: CSSStyleDeclaration = {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0,0,0,0.5)',\n zIndex: '9999',\n} as CSSStyleDeclaration;\n\nconst VIEWPORT_PADDING = 8;\n\nexport interface IframeRect {\n top: number;\n left: number;\n width: number;\n height: number;\n placement: BenjiConnectPlacement;\n}\n\nexport interface ViewportSize {\n width: number;\n height: number;\n}\n\nexport interface ResolveIframeLayoutOptions {\n warnOnInvalidAnchor?: boolean;\n preserveAnchoredLayout?: IframeRect | null;\n}\n\nfunction isPreservableAnchoredLayout(\n layout: IframeRect | null | undefined,\n): layout is IframeRect {\n return (\n layout != null && layout.placement !== BenjiConnectPlacement.CENTER\n );\n}\n\nfunction clampPreservedAnchoredLayout(\n layout: IframeRect,\n viewport: ViewportSize,\n): IframeRect {\n const maxLeft = viewport.width - layout.width - VIEWPORT_PADDING;\n const maxTop = viewport.height - layout.height - VIEWPORT_PADDING;\n const minLeft = VIEWPORT_PADDING;\n const minTop = VIEWPORT_PADDING;\n\n return {\n ...layout,\n left:\n maxLeft < minLeft\n ? minLeft\n : Math.min(Math.max(layout.left, minLeft), maxLeft),\n top:\n maxTop < minTop\n ? minTop\n : Math.min(Math.max(layout.top, minTop), maxTop),\n };\n}\n\nfunction preservedAnchoredLayoutOrCenter(\n viewport: ViewportSize,\n options: ResolveIframeLayoutOptions,\n): IframeRect {\n const { preserveAnchoredLayout } = options;\n if (isPreservableAnchoredLayout(preserveAnchoredLayout)) {\n return clampPreservedAnchoredLayout(preserveAnchoredLayout, viewport);\n }\n return centerLayout(viewport);\n}\n\nfunction isRefLikeAnchor(\n anchor: BenjiConnectAnchor,\n): anchor is { value: HTMLElement | null | undefined } {\n return (\n typeof anchor === 'object' &&\n anchor !== null &&\n !(anchor instanceof HTMLElement) &&\n 'value' in anchor\n );\n}\n\nexport function resolveAnchor(\n anchor: BenjiConnectAnchor | undefined,\n): HTMLElement | null {\n if (!anchor) {\n return null;\n }\n if (typeof anchor === 'string') {\n return document.querySelector<HTMLElement>(anchor);\n }\n if (typeof anchor === 'function') {\n const resolved = anchor();\n return resolved instanceof HTMLElement ? resolved : null;\n }\n if (isRefLikeAnchor(anchor)) {\n const el = anchor.value;\n return el instanceof HTMLElement ? el : null;\n }\n return anchor instanceof HTMLElement ? anchor : null;\n}\n\nexport function isAnchorVisible(el: HTMLElement): boolean {\n if (!el.isConnected) {\n return false;\n }\n const style = window.getComputedStyle(el);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return false;\n }\n const rect = el.getBoundingClientRect();\n return rect.width > 0 || rect.height > 0;\n}\n\nexport function resolveEffectivePlacement(\n config: Pick<BenjiConnectConfig, 'anchor' | 'placement'>,\n): BenjiConnectPlacement {\n if (!config.anchor) {\n return BenjiConnectPlacement.CENTER;\n }\n return config.placement ?? BenjiConnectPlacement.BOTTOM_END;\n}\n\nexport function defaultOffset(\n offset?: BenjiConnectPlacementOffset,\n): Required<BenjiConnectPlacementOffset> {\n return {\n top: offset?.top ?? 0,\n left: offset?.left ?? 0,\n };\n}\n\nexport function resolveIframeDimensions(viewport: ViewportSize): {\n width: number;\n height: number;\n} {\n const maxW = viewport.width - 2 * VIEWPORT_PADDING;\n const maxH = viewport.height - 2 * VIEWPORT_PADDING;\n const scale = Math.min(1, maxW / IFRAME_WIDTH, maxH / IFRAME_HEIGHT);\n return {\n width: Math.floor(IFRAME_WIDTH * scale),\n height: Math.floor(IFRAME_HEIGHT * scale),\n };\n}\n\nexport function iframeFitsHorizontally(\n viewportWidth: number,\n iframeWidth: number = IFRAME_WIDTH,\n): boolean {\n return viewportWidth >= iframeWidth + 2 * VIEWPORT_PADDING;\n}\n\nfunction centerLayout(viewport: ViewportSize): IframeRect {\n const { width, height } = resolveIframeDimensions(viewport);\n return {\n top: 0,\n left: 0,\n width,\n height,\n placement: BenjiConnectPlacement.CENTER,\n };\n}\n\nexport function fitsBelow(\n anchorBottom: number,\n offsetTop: number,\n viewportHeight: number,\n iframeHeight: number = IFRAME_HEIGHT,\n): boolean {\n const top = anchorBottom + offsetTop;\n const bottom = top + iframeHeight;\n return (\n top >= VIEWPORT_PADDING && bottom <= viewportHeight - VIEWPORT_PADDING\n );\n}\n\nfunction clampHorizontal(left: number, viewportWidth: number): number {\n const min = VIEWPORT_PADDING;\n const max = viewportWidth - IFRAME_WIDTH - VIEWPORT_PADDING;\n if (max < min) {\n return min;\n }\n return Math.min(Math.max(left, min), max);\n}\n\nfunction warnInvalidAnchor(message: string): void {\n console.warn(`[Benji Connect SDK] ${message}`);\n}\n\nexport function computeIframeRect(\n anchorElement: HTMLElement,\n placement: BenjiConnectPlacement,\n offset: BenjiConnectPlacementOffset | undefined,\n viewport: ViewportSize,\n options: ResolveIframeLayoutOptions = {},\n): IframeRect {\n const { warnOnInvalidAnchor = false } = options;\n const resolvedOffset = defaultOffset(offset);\n\n if (placement === BenjiConnectPlacement.CENTER) {\n return centerLayout(viewport);\n }\n\n if (!isAnchorVisible(anchorElement)) {\n if (isPreservableAnchoredLayout(options.preserveAnchoredLayout)) {\n return clampPreservedAnchoredLayout(\n options.preserveAnchoredLayout,\n viewport,\n );\n }\n if (warnOnInvalidAnchor) {\n warnInvalidAnchor(\n 'anchor is hidden or detached; falling back to centered modal',\n );\n }\n return centerLayout(viewport);\n }\n\n const rect = anchorElement.getBoundingClientRect();\n\n if (!fitsBelow(rect.bottom, resolvedOffset.top, viewport.height)) {\n return centerLayout(viewport);\n }\n\n if (!iframeFitsHorizontally(viewport.width)) {\n return centerLayout(viewport);\n }\n\n const top = rect.bottom + resolvedOffset.top;\n const idealLeft =\n placement === BenjiConnectPlacement.BOTTOM_END\n ? rect.right - IFRAME_WIDTH + resolvedOffset.left\n : rect.left + resolvedOffset.left;\n\n if (idealLeft < VIEWPORT_PADDING) {\n if (warnOnInvalidAnchor) {\n warnInvalidAnchor(\n 'anchor rect is unusable for placement; falling back to centered modal',\n );\n }\n return centerLayout(viewport);\n }\n\n const left = clampHorizontal(idealLeft, viewport.width);\n\n return {\n top,\n left,\n width: IFRAME_WIDTH,\n height: IFRAME_HEIGHT,\n placement,\n };\n}\n\nexport function resolveIframeLayout(\n config: BenjiConnectConfig,\n viewport: ViewportSize = {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n options: ResolveIframeLayoutOptions = {},\n): IframeRect {\n const { warnOnInvalidAnchor = true } = options;\n const placement = resolveEffectivePlacement(config);\n const anchorElement = resolveAnchor(config.anchor);\n\n if (\n warnOnInvalidAnchor &&\n placement !== BenjiConnectPlacement.CENTER &&\n !anchorElement\n ) {\n warnInvalidAnchor('anchor not found; falling back to centered modal');\n return preservedAnchoredLayoutOrCenter(viewport, options);\n }\n\n if (placement === BenjiConnectPlacement.CENTER) {\n return centerLayout(viewport);\n }\n\n if (!anchorElement) {\n return preservedAnchoredLayoutOrCenter(viewport, options);\n }\n\n return computeIframeRect(\n anchorElement,\n placement,\n config.offset,\n viewport,\n options,\n );\n}\n\n// --- DOM application ---\n\nexport interface IframeLayoutState {\n layout: IframeRect;\n lastValidAnchoredLayout: IframeRect | null;\n}\n\nexport interface RepositionListenerHandle {\n remove(): void;\n}\n\nexport function applyOverlayBaseStyle(container: HTMLDivElement): void {\n Object.assign(container.style, CONTAINER_BASE_STYLE);\n}\n\nfunction getVisualViewportOffset(): { top: number; left: number } {\n const vv = window.visualViewport;\n if (!vv) {\n return { top: 0, left: 0 };\n }\n return { top: vv.offsetTop, left: vv.offsetLeft };\n}\n\nfunction getRepositionScrollTargets(\n anchor: BenjiConnectAnchor | undefined,\n): Array<Window | HTMLElement> {\n const targets = new Set<Window | HTMLElement>([window]);\n const anchorElement = resolveAnchor(anchor);\n\n if (!anchorElement) {\n return [...targets];\n }\n\n targets.add(anchorElement);\n\n let parent: HTMLElement | null = anchorElement.parentElement;\n while (parent) {\n const { overflow, overflowX, overflowY } = window.getComputedStyle(parent);\n const overflowValue = `${overflow} ${overflowX} ${overflowY}`;\n\n if (/(auto|scroll|overlay)/.test(overflowValue)) {\n targets.add(parent);\n }\n\n parent = parent.parentElement;\n }\n\n return [...targets];\n}\n\nexport function applyIframeLayoutToElements(\n config: BenjiConnectConfig,\n container: HTMLDivElement,\n iframe: HTMLIFrameElement,\n state: IframeLayoutState,\n options: ResolveIframeLayoutOptions = { warnOnInvalidAnchor: false },\n): void {\n state.layout = resolveIframeLayout(config, undefined, {\n ...options,\n preserveAnchoredLayout: state.lastValidAnchoredLayout,\n });\n\n if (state.layout.placement !== BenjiConnectPlacement.CENTER) {\n state.lastValidAnchoredLayout = state.layout;\n }\n\n const iframeStyle = {\n ...IFRAME_STATIC_STYLE,\n width: `${state.layout.width}px`,\n height: `${state.layout.height}px`,\n };\n\n if (state.layout.placement === BenjiConnectPlacement.CENTER) {\n Object.assign(container.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'auto',\n });\n Object.assign(iframe.style, iframeStyle, {\n position: 'relative',\n top: '',\n left: '',\n });\n return;\n }\n\n Object.assign(container.style, {\n display: 'block',\n overflow: 'auto',\n });\n\n const viewportOffset = getVisualViewportOffset();\n Object.assign(iframe.style, iframeStyle, {\n position: 'fixed',\n top: `${state.layout.top + viewportOffset.top}px`,\n left: `${state.layout.left + viewportOffset.left}px`,\n });\n}\n\n/**\n * Embedded LOGIN button: the iframe fills the host's `login.container`, so the\n * host owns the box and the SDK contributes no geometry of its own. `display:\n * block` avoids the inline-element descender gap under the iframe.\n */\nexport function applyEmbeddedIframeStyle(iframe: HTMLIFrameElement): void {\n Object.assign(iframe.style, {\n display: 'block',\n width: '100%',\n height: '100%',\n border: 'none',\n colorScheme: 'normal',\n backgroundColor: 'transparent',\n });\n}\n\nexport function attachRepositionListeners(\n config: Pick<BenjiConnectConfig, 'anchor'>,\n onReposition: () => void,\n): RepositionListenerHandle {\n const repositionHandler = onReposition;\n const repositionScrollTargets = getRepositionScrollTargets(config.anchor);\n repositionScrollTargets.forEach((target) => {\n target.addEventListener('scroll', repositionHandler, { passive: true });\n });\n window.addEventListener('resize', repositionHandler);\n\n const visualViewport = window.visualViewport;\n visualViewport?.addEventListener('resize', repositionHandler);\n visualViewport?.addEventListener('scroll', repositionHandler);\n\n return {\n remove() {\n repositionScrollTargets.forEach((target) => {\n target.removeEventListener('scroll', repositionHandler);\n });\n window.removeEventListener('resize', repositionHandler);\n visualViewport?.removeEventListener('resize', repositionHandler);\n visualViewport?.removeEventListener('scroll', repositionHandler);\n },\n };\n}\n","/**\n * LOGIN query params on the embedded Connect button iframe. Lockstep with\n * Benji Connect `src/constants/login.ts`, which reads them in `login-button.ts`.\n */\nexport const LOGIN_BUTTON_QUERY_KEYS = {\n connectToken: 'connect_token',\n configToken: 'config_token',\n partnerAuthLink: 'partner_auth_link',\n windowTarget: 'login_window_target',\n buttonText: 'login_button_text',\n} as const;\n\n/**\n * Benji Connect serves the button from its own lightweight Vite entry rather\n * than the SPA root, so it boots without Pinia, the router, or analytics.\n */\nexport const LOGIN_BUTTON_PATH = '/login-button.html';\n","import { BenjiConnectAuthAction } from \"./auth\";\n\n// Known event names coming from the SDK transport (postMessage)\nexport enum BenjiConnectEventType {\n AUTH_SUCCESS = 'AUTH_SUCCESS',\n FLOW_EXIT = 'FLOW_EXIT',\n FLOW_SUCCESS = 'FLOW_SUCCESS',\n EVENT = 'EVENT',\n ERROR = 'ERROR',\n /** LOGIN embedded button: Connect resolved the partner auth link and rendered the button. */\n LOGIN_READY = 'LOGIN_READY',\n /** LOGIN embedded button: pointer or focus entered the in-iframe button. */\n LOGIN_HOVER = 'LOGIN_HOVER',\n /** LOGIN embedded button: the button was pressed, before the partner tab opens. */\n LOGIN_CLICKED = 'LOGIN_CLICKED',\n}\n\n// Known exit trigger types coming from the SDK transport (postMessage)\nexport enum BenjiConnectExitTrigger {\n ACTION_BUTTON_CLICKED = 'ACTION_BUTTON_CLICKED',\n BACK_TO_MERCHANT_CLICKED = 'BACK_TO_MERCHANT_CLICKED', // deprecated\n CLOSE_BUTTON_CLICKED = 'CLOSE_BUTTON_CLICKED',\n TAPPED_OUT_OF_BOUNDS = 'TAPPED_OUT_OF_BOUNDS',\n /** SDK-detected partner-auth window loss (not a Connect UI close click). */\n WINDOW_CLOSE_DETECTED = 'WINDOW_CLOSE_DETECTED',\n /** @deprecated Use WINDOW_CLOSE_DETECTED. Same meaning; no longer emitted by this SDK version. */\n POPUP_CLOSED = 'POPUP_CLOSED',\n}\n\nexport enum BenjiConnectErrorName {\n UNEXPECTED_ERROR = 'unexpected_error',\n PARTNER_CONNECT_ERROR = 'partner_connect_error'\n}\n\nexport type BenjiConnectErrorID = '400' | '500'; // Placeholders for now\n\n// Transport-layer token (raw, unprocessed from postMessage)\nexport interface BenjiConnectEventToken {\n access_token?: string;\n refresh_token?: string;\n expires_at?: string | number;\n exchange_token?: string;\n}\n\nexport interface BenjiConnectEventUserData {\n user: {\n id: number\n first_name: string\n last_name: string\n uuid?: string\n }\n status: BenjiConnectEventUserStatusData\n extra_data?: {\n total_rewards_earned?: number\n total_rewards_redeemed?: number\n created_date?: string\n }\n}\n\nexport interface BenjiConnectEventTransactionData {\n action: string;\n amount: number;\n trigger_event_id: string;\n trigger_name: string;\n}\n\nexport interface BenjiConnectEventUserStatusData {\n status_id: string\n num_of_rewards: number\n reward_status: string\n partner_status_tier_id?: number\n}\n\n// Basic structure for Benji Connect SDK typed events\nexport interface BenjiConnectEvent {\n type: BenjiConnectEventType;\n data?: BenjiConnectEventData;\n}\n\nexport interface BenjiConnectEventData {\n [k: string]: unknown;\n}\n\nexport interface BenjiConnectEventMessage<K extends BenjiConnectEventType = BenjiConnectEventType> {\n type: K; // discriminant\n data: BenjiConnectEventDataMap[K];\n}\n\nexport interface BenjiConnectAuthSuccessEventData {\n action: BenjiConnectAuthAction;\n metadata?: BenjiConnectEventUserData;\n token?: BenjiConnectEventToken,\n transaction?: BenjiConnectEventTransactionData;\n}\n\nexport interface BenjiConnectFlowExitEventData {\n step: string;\n trigger: BenjiConnectExitTrigger;\n}\n\nexport interface BenjiConnectErrorEventData {\n error: Error;\n}\n\n/** LOGIN embedded-button lifecycle events carry no payload of their own. */\nexport type BenjiConnectLoginButtonEventData = Record<string, never>;\n\n// Canonical event map \nexport type BenjiConnectEventDataMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: BenjiConnectAuthSuccessEventData;\n [BenjiConnectEventType.FLOW_EXIT]: BenjiConnectFlowExitEventData;\n [BenjiConnectEventType.FLOW_SUCCESS]: BenjiConnectAuthSuccessEventData;\n [BenjiConnectEventType.EVENT]: BenjiConnectEventData;\n [BenjiConnectEventType.ERROR]: BenjiConnectErrorEventData;\n [BenjiConnectEventType.LOGIN_READY]: BenjiConnectLoginButtonEventData;\n [BenjiConnectEventType.LOGIN_HOVER]: BenjiConnectLoginButtonEventData;\n [BenjiConnectEventType.LOGIN_CLICKED]: BenjiConnectLoginButtonEventData;\n\n // Optional catch-all fan-out\n '*': { type: BenjiConnectEventType; data: BenjiConnectEventDataMap[BenjiConnectEventType] };\n};","import { BenjiConnectAuthToken } from '../types/auth';\nimport { BenjiConnectEventToken, BenjiConnectEventType } from '../types/event';\n\nconst CONNECT_MESSAGE_TYPES = new Set<string>(Object.values(BenjiConnectEventType));\n\nexport function isConnectMessageType(data: unknown): boolean {\n if (!data || typeof data !== 'object') return false;\n const type = (data as { type?: string }).type;\n return typeof type === 'string' && CONNECT_MESSAGE_TYPES.has(type);\n}\n\nexport const extractAccessToken = (token?: BenjiConnectEventToken | string): string =>\n typeof token === 'string' ? token : (token?.access_token ?? '');\n\nexport const extractExchangeToken = (token?: BenjiConnectEventToken | string): string =>\n typeof token === 'string' ? token : (token?.exchange_token ?? '');\n\nexport const mapEventToConnectToken = (data?: BenjiConnectEventToken): BenjiConnectAuthToken => ({\n access_token: data?.access_token ?? '',\n refresh_token: data?.refresh_token ?? '',\n expires_at: data?.expires_at ?? ''\n});\n","import { BenjiConnectEventUserData } from \"../types/event\";\nimport { BenjiConnectUserData } from \"../types/user\";\n\nexport function isConnectUserData (\n input: BenjiConnectUserData | Record<string, any>\n): boolean {\n if (!input) return false;\n const data = mapEventToConnectUserData(input);\n if (data.user.id != 0) return true;\n return false;\n}\n\nexport const mapEventToConnectUserData = (\n data?: BenjiConnectEventUserData | Record<string, any>\n): BenjiConnectUserData => ({\n user: {\n id: data?.user?.id ?? 0,\n first_name: data?.user?.first_name ?? '',\n last_name: data?.user?.last_name ?? '',\n uuid: data?.user?.uuid \n },\n status: {\n status_id: data?.status?.status_id ?? '',\n num_of_rewards: data?.status?.num_of_rewards ?? 0,\n reward_status: data?.status?.reward_status ?? '',\n partner_status_tier_id: data?.status?.partner_status_tier_id\n },\n extra_data: {\n total_rewards_earned: data?.extra_data?.total_rewards_earned,\n total_rewards_redeemed: data?.extra_data?.total_rewards_redeemed,\n created_date: data?.extra_data?.created_date\n }\n});\n","import { BenjiConnectEventTransactionData } from \"../types/event\";\nimport { BenjiConnectTransactionData } from \"../types/transaction\";\n\nexport const mapEventToConnectTransactionData = (data?: BenjiConnectEventTransactionData): BenjiConnectTransactionData | null => {\n if (!data) return null;\n return {\n action: data.action,\n amount: data.amount,\n trigger_event_id: data.trigger_event_id,\n trigger_name: data.trigger_name\n };\n}","import {\n BenjiConnectLoginSurface,\n BenjiConnectMetadata,\n BenjiConnectMode,\n BenjiConnectOnErrorData,\n BenjiConnectOnEventData,\n BenjiConnectOnExitData,\n BenjiConnectOnExitMetadata,\n BenjiConnectOnSuccessData,\n BenjiConnectOnSuccessMetadata,\n} from './config';\n\nimport { \n extractAccessToken,\n extractExchangeToken,\n mapEventToConnectToken \n} from '../utils/auth';\n\nimport { BenjiConnectAuthAction } from './auth';\n\nimport { buildContext } from '../utils/config';\nimport { mapEventToConnectUserData } from '../utils/user';\n\nimport { \n BenjiConnectAuthSuccessEventData,\n BenjiConnectErrorEventData, \n BenjiConnectEventDataMap, \n BenjiConnectEventMessage, \n BenjiConnectEventType, \n BenjiConnectFlowExitEventData\n} from './event';\nimport { mapEventToConnectTransactionData } from '../utils/transaction';\n\nexport type MessageRouterContext = {\n iframe: HTMLIFrameElement | null;\n mode: BenjiConnectMode;\n surface: BenjiConnectLoginSurface;\n};\n\nexport type MessageRouterConfig = {\n onSuccess?: (\n token: string, \n metadata: BenjiConnectOnSuccessMetadata\n ) => void;\n onError?: (\n error: Error,\n error_id: string,\n metadata: BenjiConnectMetadata\n ) => void;\n onExit?: (\n metadata: BenjiConnectOnExitMetadata\n ) => void;\n onEvent?: (\n type: BenjiConnectEventType, \n metadata: BenjiConnectMetadata\n ) => void;\n onLoginReady?: () => void;\n onLoginHover?: () => void;\n onLoginClicked?: () => void;\n close?: () => void;\n};\n\nexport const mapToAuthSuccessData = (\n message: BenjiConnectEventMessage<BenjiConnectEventType.AUTH_SUCCESS>,\n data: BenjiConnectAuthSuccessEventData\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n action: data.action,\n token: mapEventToConnectToken(data.token),\n transactionData: mapEventToConnectTransactionData(data.transaction),\n userData: mapEventToConnectUserData(data.metadata)\n }\n };\n};\n\nexport const mapToOnExitData = (data: BenjiConnectFlowExitEventData): BenjiConnectOnExitData => {\n return {\n metadata: {\n context: buildContext(),\n step: data.step,\n trigger: data.trigger\n }\n };\n};\n\nexport const mapToOnSuccessData = (data: BenjiConnectAuthSuccessEventData): BenjiConnectOnSuccessData => {\n \n const token = data.action === BenjiConnectAuthAction.Login\n ? extractExchangeToken(data.token)\n : extractAccessToken(data.token);\n\n let metadata: BenjiConnectOnSuccessMetadata = {\n context: buildContext(),\n action: data.action,\n user_data: data.metadata\n };\n\n if (data.transaction) {\n metadata.transaction_data = data.transaction;\n }\n \n return { token, metadata };\n};\n\nexport const mapToOnErrorData = (data: BenjiConnectErrorEventData): BenjiConnectOnErrorData => {\n return {\n error: data.error,\n error_id: '500', // Placeholder\n metadata: {\n context: buildContext()\n }\n };\n};\n\nexport const mapToOnEventData = <K extends BenjiConnectEventType>(\n message: BenjiConnectEventMessage<K>,\n data: BenjiConnectEventDataMap[K]\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n ...data\n }\n };\n};\n\n/**\n * LOGIN embedded-button lifecycle. Payload-free, so the mapper only stamps\n * context — but it goes through a mapper like every other inbound event rather\n * than being built inline in `MessageRouter`.\n */\nexport const mapToLoginButtonEventData = <\n K extends\n | BenjiConnectEventType.LOGIN_READY\n | BenjiConnectEventType.LOGIN_HOVER\n | BenjiConnectEventType.LOGIN_CLICKED,\n>(\n message: BenjiConnectEventMessage<K>,\n _data: BenjiConnectEventDataMap[K],\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n },\n };\n};\n\nexport type BenjiConnectCallbackDataMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: BenjiConnectOnEventData;\n [BenjiConnectEventType.FLOW_EXIT]: BenjiConnectOnExitData;\n [BenjiConnectEventType.FLOW_SUCCESS]: BenjiConnectOnSuccessData;\n [BenjiConnectEventType.ERROR]: BenjiConnectOnErrorData;\n [BenjiConnectEventType.EVENT]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_READY]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_HOVER]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_CLICKED]: BenjiConnectOnEventData;\n '*': BenjiConnectOnEventData;\n};\n\nexport const BenjiConnectCallbackMapperMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: mapToAuthSuccessData,\n [BenjiConnectEventType.FLOW_EXIT]: mapToOnExitData,\n [BenjiConnectEventType.FLOW_SUCCESS]: mapToOnSuccessData,\n [BenjiConnectEventType.ERROR]: mapToOnErrorData,\n [BenjiConnectEventType.EVENT]: mapToOnEventData,\n [BenjiConnectEventType.LOGIN_READY]: mapToLoginButtonEventData,\n [BenjiConnectEventType.LOGIN_HOVER]: mapToLoginButtonEventData,\n [BenjiConnectEventType.LOGIN_CLICKED]: mapToLoginButtonEventData,\n} as const;\n\n","import { \n Endpoints\n} from '../config';\n\nimport { BenjiConnectLoginSurface, BenjiConnectMode } from '../types/config';\nimport {\n BenjiConnectEventType,\n type BenjiConnectEventMessage,\n} from '../types/event';\n\nimport type {\n BenjiConnectOnSuccessData,\n BenjiConnectOnExitData,\n} from '../types/config';\nimport type { BenjiConnectHostMessage } from '../types/host';\n\nimport {\n BenjiConnectCallbackMapperMap,\n MessageRouterConfig,\n mapToOnEventData,\n type MessageRouterContext,\n} from '../types/router';\nimport { isConnectMessageType } from '../utils/auth';\n\n/**\n * Host ↔ Benji Connect transport. Connect owns the partner-auth window, so this\n * router never forwards partner traffic: every message it accepts comes from the\n * Connect iframe on the Connect origin, and every message it sends goes back to\n * that same iframe.\n *\n * One router per `ConnectSDK`, deliberately. A LOGIN page mounts a button per\n * call to action, so several Connect frames post to the same host window at\n * once; a shared router would hand every frame's events to whichever instance\n * registered last, and tearing one button down would silence the rest. Each\n * router therefore keeps its own listener and answers only to its own frame —\n * see `isFromOwnFrame`.\n */\nexport class MessageRouter {\n\n private config: MessageRouterConfig = {};\n private iframe: HTMLIFrameElement | null = null;\n private mode: BenjiConnectMode = BenjiConnectMode.CONNECT;\n private surface: BenjiConnectLoginSurface = BenjiConnectLoginSurface.MODAL;\n private connectOrigin = '';\n private configuredListeners = false;\n\n configureMessageRouter(config: MessageRouterConfig) {\n this.config = config;\n }\n\n setContext(context: MessageRouterContext) {\n this.iframe = context.iframe;\n this.mode = context.mode;\n this.surface = context.surface;\n this.connectOrigin = new URL(Endpoints.benji_connect_auth_url).origin;\n }\n\n setMode(mode: BenjiConnectMode) {\n this.mode = mode;\n }\n\n /** Host → Connect iframe. Always origin-targeted; never `'*'`. */\n postToConnect(message: BenjiConnectHostMessage): boolean {\n const iframeWindow = this.iframe?.contentWindow ?? null;\n if (!iframeWindow) {\n console.warn('[Benji Connect SDK] Cannot post to Connect, no iframe mounted', message.type);\n return false;\n }\n\n const targetOrigin =\n this.connectOrigin || new URL(Endpoints.benji_connect_auth_url).origin;\n iframeWindow.postMessage(message, targetOrigin);\n return true;\n }\n\n private errorEventHandler = (event: Event) => {\n return this.handleErrorMessage(event);\n };\n\n private messageEventHandler = (event: MessageEvent<unknown>) => {\n return this.handleMessage(event);\n };\n\n addEventListeners() {\n if (this.configuredListeners) return;\n window.addEventListener('error', this.errorEventHandler);\n window.addEventListener('unhandledrejection', this.errorEventHandler);\n window.addEventListener('message', this.messageEventHandler);\n this.configuredListeners = true;\n }\n\n removeEventListeners() {\n window.removeEventListener('error', this.errorEventHandler);\n window.removeEventListener('unhandledrejection', this.errorEventHandler);\n window.removeEventListener('message', this.messageEventHandler);\n this.configuredListeners = false;\n this.iframe = null;\n this.mode = BenjiConnectMode.CONNECT;\n this.surface = BenjiConnectLoginSurface.MODAL;\n this.connectOrigin = '';\n }\n\n handleErrorMessage(event: Event) { \n switch(event.type) {\n case 'error':\n case 'unhandledrejection': {\n break;\n }\n default: {\n console.error('[Benji Connect SDK] Received Unknown error message', event);\n break;\n }\n }\n }\n\n /**\n * The origin check alone is not enough when the page hosts several Connect\n * frames: they all share it. Matching the source window is what keeps a hover\n * on one button from being reported as a hover on another.\n */\n private isFromOwnFrame(event: MessageEvent<unknown>): boolean {\n const iframeWindow = this.iframe?.contentWindow ?? null;\n if (!iframeWindow) return false;\n return event.source === iframeWindow;\n }\n\n handleMessage(event: MessageEvent<unknown>) {\n if (!isConnectMessageType(event.data)) return;\n\n const expectedOrigin: string = new URL(Endpoints.benji_connect_auth_url).origin;\n if (!event || event.origin !== expectedOrigin) {\n console.warn('[Benji Connect SDK] Skipped message, received event from unexpected origin', event.origin, expectedOrigin);\n return;\n }\n\n if (!this.isFromOwnFrame(event)) return;\n\n const raw = event.data;\n if (!raw || typeof raw !== 'object') return;\n\n const partial = raw as Partial<BenjiConnectEventMessage>;\n if (typeof partial.type !== 'string') return;\n \n const message = partial as BenjiConnectEventMessage;\n\n switch (message.type) {\n\n case BenjiConnectEventType.AUTH_SUCCESS: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.AUTH_SUCCESS>;\n const callbackData = BenjiConnectCallbackMapperMap.AUTH_SUCCESS(connectMessage, connectMessage.data);\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.FLOW_EXIT: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.FLOW_EXIT>;\n const callbackData = BenjiConnectCallbackMapperMap.FLOW_EXIT(connectMessage.data) as BenjiConnectOnExitData;\n this.config.onExit?.(callbackData.metadata);\n // Embedded button: Connect returns to ready after window loss and\n // posts FLOW_EXIT as a host toast. Unmounting would remove the retry\n // surface. Hosts that want the button gone still call close().\n if (this.surface !== BenjiConnectLoginSurface.EMBEDDED_BUTTON) {\n this.config.close?.();\n }\n break;\n }\n\n case BenjiConnectEventType.FLOW_SUCCESS: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.FLOW_SUCCESS>;\n const callbackData = BenjiConnectCallbackMapperMap.FLOW_SUCCESS(connectMessage.data) as BenjiConnectOnSuccessData;\n this.config.onSuccess?.(callbackData.token, callbackData.metadata);\n // Terminal: the exchange finished. Unlike FLOW_EXIT on the embedded\n // button, this session is done.\n if (this.mode === BenjiConnectMode.LOGIN) {\n this.config.close?.();\n }\n break;\n }\n\n case BenjiConnectEventType.ERROR: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.ERROR>;\n const callbackData = BenjiConnectCallbackMapperMap.ERROR(connectMessage.data);\n this.config.onError?.(callbackData.error, callbackData.error_id, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.EVENT: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.EVENT>;\n const callbackData = mapToOnEventData(connectMessage, connectMessage.data);\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_READY: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_READY>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_READY(connectMessage, connectMessage.data);\n this.config.onLoginReady?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_HOVER: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_HOVER>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_HOVER(connectMessage, connectMessage.data);\n this.config.onLoginHover?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_CLICKED: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_CLICKED>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_CLICKED(connectMessage, connectMessage.data);\n this.config.onLoginClicked?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n default: {\n const _exhaustive: never = message.type;\n console.warn('[Benji Connect SDK] Unhandled connect message type', _exhaustive);\n break;\n }\n\n }\n }\n\n}\n","import type { BenjiConnectLoginButtonTheme } from '../types/config';\nimport type { BenjiConnectLoginButtonThemeWire } from '../types/host';\n\nconst WIRE_KEYS: {\n [K in keyof BenjiConnectLoginButtonTheme]-?: keyof BenjiConnectLoginButtonThemeWire;\n} = {\n background: 'background',\n backgroundHover: 'background_hover',\n backgroundDisabled: 'background_disabled',\n text: 'text',\n textDisabled: 'text_disabled',\n border: 'border',\n borderWidth: 'border_width',\n borderRadius: 'border_radius',\n fontFamily: 'font_family',\n fontSize: 'font_size',\n fontWeight: 'font_weight',\n lineHeight: 'line_height',\n textTransform: 'text_transform',\n};\n\nexport function toWireLoginButtonTheme(\n theme: BenjiConnectLoginButtonTheme | undefined,\n): BenjiConnectLoginButtonThemeWire | undefined {\n if (!theme) return undefined;\n\n const wire: BenjiConnectLoginButtonThemeWire = {};\n let hasValue = false;\n\n (Object.keys(WIRE_KEYS) as (keyof BenjiConnectLoginButtonTheme)[]).forEach(\n (key) => {\n const value = theme[key];\n if (value == null || value === '') return;\n wire[WIRE_KEYS[key]] = value;\n hasValue = true;\n },\n );\n\n return hasValue ? wire : undefined;\n}\n","/// <reference path=\"./global.d.ts\" />\n\nimport { \n configureConfig, \n Endpoints,\n} from './config';\n\nimport { \n type BenjiConnectConfig,\n type BenjiConnectConfigUpdate,\n BenjiConnectEnvironment,\n BenjiConnectLoginSurface,\n BenjiConnectLoginWindowTarget,\n BenjiConnectMode,\n BenjiConnectPlacement,\n PartnerIntegrationType,\n} from './types/config';\n\nimport { \n buildContext, \n mapToConnectEnvironment \n} from './utils/config';\n\nimport {\n resolveLoginContainer,\n resolveLoginSurface,\n} from './utils/loginSurface';\n\nimport {\n IFRAME_HEIGHT,\n IFRAME_WIDTH,\n applyEmbeddedIframeStyle,\n applyIframeLayoutToElements,\n applyOverlayBaseStyle,\n attachRepositionListeners,\n type IframeLayoutState,\n type RepositionListenerHandle,\n} from './utils/placement';\n\nimport { LOGIN_BUTTON_PATH, LOGIN_BUTTON_QUERY_KEYS } from './constants/login';\nimport { MessageRouter } from './router/message';\nimport { BenjiConnectExitTrigger } from './types/event';\nimport { BenjiConnectHostMessageType } from './types/host';\nimport { toWireLoginButtonTheme } from './utils/loginButtonTheme';\n\nclass ConnectSDK {\n\n private sdkConfig: BenjiConnectConfig;\n private iframe: HTMLIFrameElement | null = null;\n private container: HTMLDivElement | null = null;\n private layoutState: IframeLayoutState = {\n layout: {\n top: 0,\n left: 0,\n width: IFRAME_WIDTH,\n height: IFRAME_HEIGHT,\n placement: BenjiConnectPlacement.CENTER,\n },\n lastValidAnchoredLayout: null,\n };\n private repositionListeners: RepositionListenerHandle | null = null;\n private isClosing = false;\n\n /**\n * One router per instance: a LOGIN page mounts a button per call to action, so\n * the routers must not share callbacks, a frame reference, or a listener.\n */\n private readonly router = new MessageRouter();\n\n private onIframeLoad = (): void => {\n if (this.isClosing || !this.iframe) return;\n this.postHostConfig();\n };\n\n private postHostConfig(): void {\n if (!this.iframe) return;\n const login_button_theme = toWireLoginButtonTheme(\n this.sdkConfig.login?.buttonTheme,\n );\n const login_button_text = this.sdkConfig.login?.buttonText;\n this.router.postToConnect({\n type: BenjiConnectHostMessageType.HOST_CONFIG_UPDATE,\n data: {\n connect_token: this.sdkConfig.token,\n config_token: this.sdkConfig.tokenData?.configToken,\n partner_auth_link: this.sdkConfig.tokenData?.partnerAuthLink,\n ...(login_button_theme ? { login_button_theme } : {}),\n ...(login_button_text !== undefined\n ? { login_button_text: login_button_text.trim() }\n : {}),\n },\n });\n }\n\n constructor(config: BenjiConnectConfig) {\n\n this.sdkConfig = config;\n\n // Validations\n if (!this.sdkConfig.environment) throw new Error('Environment is required');\n if (!this.sdkConfig.token) throw new Error('Connect token is required');\n\n // Set internal config for environment based on consumer input at runtime\n const environment: BenjiConnectEnvironment = mapToConnectEnvironment(this.sdkConfig.environment);\n this.sdkConfig.environment = environment;\n configureConfig(environment);\n }\n\n private resolveAuthType(): PartnerIntegrationType | undefined {\n return this.sdkConfig.tokenData?.authType ?? this.sdkConfig.authType;\n }\n\n private resolveMode(): BenjiConnectMode {\n return this.sdkConfig.mode ?? BenjiConnectMode.CONNECT;\n }\n\n private resolveSurface(): BenjiConnectLoginSurface {\n return resolveLoginSurface({\n mode: this.resolveMode(),\n authType: this.resolveAuthType(),\n configured: this.sdkConfig.login?.surface,\n });\n }\n\n private isEmbeddedButton(): boolean {\n return this.resolveSurface() === BenjiConnectLoginSurface.EMBEDDED_BUTTON;\n }\n\n private resolveLoginWindowTarget(): BenjiConnectLoginWindowTarget {\n return (\n this.sdkConfig.login?.windowTarget ?? BenjiConnectLoginWindowTarget.TAB\n );\n }\n\n private isSessionActive(): boolean {\n return this.iframe != null;\n }\n\n initialize() {\n this.router.configureMessageRouter({\n onSuccess: this.sdkConfig.onSuccess,\n onError: this.sdkConfig.onError,\n onExit: this.sdkConfig.onExit,\n onEvent: this.sdkConfig.onEvent,\n onLoginReady: this.sdkConfig.onLoginReady,\n onLoginHover: this.sdkConfig.onLoginHover,\n onLoginClicked: this.sdkConfig.onLoginClicked,\n close: () => this.close(),\n });\n\n // TODO: Tracker.configureWithOptions(sdkOptions);\n // TODO: Tracker.trackSDKInitialized();\n }\n\n async open() {\n if (this.isSessionActive()) return;\n\n this.initialize();\n this.router.setMode(this.resolveMode());\n this.openUI();\n // Listeners attach only after a frame exists. A missing login.container\n // reports through onError and returns without an iframe — attaching first\n // would leak window listeners that cleanup used to skip.\n if (!this.iframe) return;\n this.router.addEventListeners();\n // TODO: Track SDK Opened Tracker.trackSDKOpened();\n }\n\n /**\n * Hands the mounted iframe a refreshed connect token so a long-lived host page\n * does not go stale, without remounting and losing the resolved auth link.\n */\n updateConfig(update: BenjiConnectConfigUpdate): void {\n if (update.token) this.sdkConfig.token = update.token;\n if (update.tokenData) {\n this.sdkConfig.tokenData = {\n ...this.sdkConfig.tokenData,\n ...update.tokenData,\n };\n }\n if (update.login) {\n this.sdkConfig.login = {\n ...this.sdkConfig.login,\n ...update.login,\n ...(update.login.buttonTheme\n ? {\n buttonTheme: {\n ...this.sdkConfig.login?.buttonTheme,\n ...update.login.buttonTheme,\n },\n }\n : {}),\n };\n }\n\n this.postHostConfig();\n }\n\n private syncContext(): void {\n this.router.setContext({\n iframe: this.iframe,\n mode: this.resolveMode(),\n surface: this.resolveSurface(),\n });\n }\n\n private buildIframeUrl(): string {\n const embedded = this.isEmbeddedButton();\n const url = new URL(\n embedded ? LOGIN_BUTTON_PATH : '',\n Endpoints.benji_connect_auth_url,\n );\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.connectToken, this.sdkConfig.token);\n url.searchParams.set('t', String(Date.now()));\n if (this.sdkConfig.mode != null) {\n url.searchParams.set('mode', String(this.sdkConfig.mode));\n }\n\n if (!embedded) return url.toString();\n\n // Connect owns window.open, so it needs the auth link, its OAuth state\n // nonce, and the shell choice up front — resolved at load, long before any\n // click, which is what removes the bootstrap race.\n url.searchParams.set(\n LOGIN_BUTTON_QUERY_KEYS.windowTarget,\n this.resolveLoginWindowTarget(),\n );\n const buttonText = this.sdkConfig.login?.buttonText?.trim();\n if (buttonText) {\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.buttonText, buttonText);\n }\n const { configToken, partnerAuthLink } = this.sdkConfig.tokenData ?? {};\n if (configToken) {\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.configToken, configToken);\n }\n if (partnerAuthLink) {\n url.searchParams.set(\n LOGIN_BUTTON_QUERY_KEYS.partnerAuthLink,\n partnerAuthLink,\n );\n }\n return url.toString();\n }\n\n openUI() {\n if (this.iframe) return;\n\n const embedded = this.isEmbeddedButton();\n const host = embedded\n ? resolveLoginContainer(this.sdkConfig.login?.container)\n : null;\n\n if (embedded && !host) {\n // No iframe, so open() must not attach window listeners. cleanup()\n // always runs close(), which can tear listeners down if a later\n // change reorders that again.\n console.warn('[Connect SDK] login.container is required for the embedded LOGIN button');\n this.sdkConfig.onError?.(\n new Error('Sign-in could not be started.'),\n '400',\n { context: buildContext() },\n );\n return;\n }\n\n this.iframe = document.createElement('iframe');\n // Bind the router before `src` so iframe `load` can post HOST_CONFIG_UPDATE\n // (theme + tokens) once Connect's listener is up.\n this.syncContext();\n this.iframe.addEventListener('load', this.onIframeLoad);\n this.iframe.src = this.buildIframeUrl();\n\n if (embedded && host) {\n this.iframe.title = 'Sign in';\n applyEmbeddedIframeStyle(this.iframe);\n host.appendChild(this.iframe);\n return;\n }\n\n this.container = document.createElement('div');\n applyOverlayBaseStyle(this.container);\n this.container.appendChild(this.iframe);\n document.body.appendChild(this.container);\n\n applyIframeLayoutToElements(\n this.sdkConfig,\n this.container,\n this.iframe,\n this.layoutState,\n { warnOnInvalidAnchor: true },\n );\n this.repositionListeners = attachRepositionListeners(\n this.sdkConfig,\n () => {\n if (!this.iframe || !this.container) return;\n applyIframeLayoutToElements(\n this.sdkConfig,\n this.container,\n this.iframe,\n this.layoutState,\n );\n },\n );\n\n this.container.addEventListener('click', (e) => {\n if (e.target === this.container) {\n // Trigger exit when user taps outside modal bounds\n this.sdkConfig.onExit?.({\n context: buildContext(),\n trigger: BenjiConnectExitTrigger.TAPPED_OUT_OF_BOUNDS\n });\n this.close();\n }\n });\n }\n\n close() {\n this.isClosing = true;\n this.router.removeEventListeners();\n\n if (!this.iframe) {\n this.isClosing = false;\n return;\n }\n\n this.repositionListeners?.remove();\n this.repositionListeners = null;\n this.layoutState.lastValidAnchoredLayout = null;\n\n this.iframe.removeEventListener('load', this.onIframeLoad);\n\n // Embedded buttons mount straight into the host's container, so there is no\n // SDK-owned overlay to detach.\n const mountedNode = this.container ?? this.iframe;\n if (mountedNode.parentNode) {\n mountedNode.parentNode.removeChild(mountedNode);\n }\n this.iframe = null;\n this.container = null;\n this.isClosing = false;\n }\n\n cleanup() {\n // Always tear down: close() removes window listeners even when no\n // iframe was mounted (a failed open used to leak them).\n this.close();\n }\n\n ping() { return 'pong'; }\n}\n\nexport default ConnectSDK;\n","/// <reference path=\"./global.d.ts\" />\nimport ConnectSDK from './connect-sdk';\n(globalThis as any).ConnectSDK = ConnectSDK;"],"mappings":"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","names":["endpoints","project_environment","endpoints","project_environment","endpoints","project_environment","BenjiConnectEventType","data","data","data","data","_a","_b"]}
1
+ {"version":3,"sources":["../src/config/production.ts","../src/config/sandbox.ts","../src/config/development.ts","../src/config/local.defaults.ts","../src/utils/environment.ts","../src/config/index.ts","../src/utils/config.ts","../src/utils/loginSurface.ts","../src/utils/placement.ts","../src/constants/login.ts","../src/types/event.ts","../src/utils/auth.ts","../src/utils/user.ts","../src/utils/transaction.ts","../src/types/router.ts","../src/router/message.ts","../src/utils/loginButtonTheme.ts","../src/connect-sdk.ts","../src/global.ts"],"sourcesContent":["export const project_environment: string = 'production';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url':'https://verifyapp.withbenji.com',\n 'benji_connect_auth_service_url' : 'https://authservice.withbenji.com'\n}","export const project_environment: string = 'sandbox';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url':'https://verifyapp-staging.withbenji.com',\n 'benji_connect_auth_service_url' : 'https://authservice-staging.withbenji.com'\n}","export const project_environment: string = 'development';\n\nexport const endpoints: Record<string, string> = {\n 'benji_connect_auth_url': 'https://verifyapp-dev.withbenji.com',\n 'benji_connect_auth_service_url': 'https://authservice-dev.withbenji.com',\n};","/**\n * Build-time fallback when gitignored `local.ts` is absent (CI, fresh clones).\n * Same endpoints as development — not machine-specific localhost overrides.\n * Copy to `local.ts` locally for localhost URLs; see RELEASE.md.\n */\nexport const project_environment: string = 'local';\n\nexport const endpoints: Record<string, string> = {\n benji_connect_auth_url: 'https://verifyapp-dev.withbenji.com',\n benji_connect_auth_service_url: 'https://authservice-dev.withbenji.com',\n};\n","/** Hostnames that browsers use for loopback when typed literally in the URL bar. */\nexport const LOCAL_HOSTNAMES = ['localhost', '127.0.0.1', '::1', '[::1]'] as const;\n\nconst LOCAL_HOSTNAME_SET: ReadonlySet<string> = new Set(LOCAL_HOSTNAMES);\n\nexport function isLocalHost(\n hostname: string = typeof window !== 'undefined' ? window.location.hostname : ''\n): boolean {\n if (LOCAL_HOSTNAME_SET.has(hostname)) {\n return true;\n }\n // IPv4 loopback block 127.0.0.0/8 — covers 127.0.0.1 without listing every address\n if (hostname.startsWith('127.')) {\n return true;\n }\n return false;\n}\n","import * as productionConfig from './production';\nimport * as sandboxConfig from './sandbox';\nimport * as developmentConfig from './development';\nimport * as localConfig from './local';\nimport { BenjiConnectEnvironment } from '../types/config';\nimport { isLocalHost } from '../utils/environment';\n\nexport type EnvironmentConfigModule = {\n project_environment: string;\n endpoints: Record<string, string>;\n};\n\nconst env = typeof process !== 'undefined' ? process.env : {};\nlet data: EnvironmentConfigModule = developmentConfig;\ntype EndpointConfig = typeof developmentConfig.endpoints;\nexport let Endpoints: EndpointConfig = getEndpoints();\nexport let Environment = BenjiConnectEnvironment.DEVELOPMENT;\n\nexport function configureConfig(environment: BenjiConnectEnvironment) {\n if (environment == 'production') {\n console.log('[Connect SDK] configuring with environment production');\n data = productionConfig;\n } else if (environment == 'sandbox') {\n console.log('[Connect SDK] configuring with environment sandbox');\n data = sandboxConfig;\n } else if (environment == 'development') {\n console.log('[Connect SDK] configuring with environment development');\n data = developmentConfig;\n } else if (environment == 'local') {\n if (isLocalHost()) {\n console.log('[Connect SDK] configuring with environment local');\n data = localConfig;\n } else {\n console.log(\n '[Connect SDK] local environment requested on non-local host; using development'\n );\n data = developmentConfig;\n }\n }\n Endpoints = getEndpoints();\n Environment = getEnvironment();\n}\n\nfunction getEndpoints(): EndpointConfig {\n const entries = Object.entries(data.endpoints).map(([key, value]) => {\n const override = env?.[key] || value;\n return [key, override] as const;\n });\n return Object.fromEntries(entries) as EndpointConfig;\n}\n\nfunction getEnvironment(): BenjiConnectEnvironment {\n return data['project_environment'] as BenjiConnectEnvironment;\n}\n\nexport const Namespace = __NAMESPACE__;\nexport const Version = __VERSION__;\n","import { BenjiConnectEnvironment } from \"../types/config\";\nimport { isLocalHost } from \"./environment\";\n\nexport const buildContext = () => ({\n namespace: typeof __NAMESPACE__ !== 'undefined' && __NAMESPACE__ ? __NAMESPACE__ : 'benji-connect-sdk',\n version: typeof __VERSION__ !== 'undefined' && __VERSION__ ? String(__VERSION__) : '0.0.0',\n});\n\nexport function isBenjiConnectEnvironment(\n environment: unknown\n): environment is BenjiConnectEnvironment {\n return (\n environment === BenjiConnectEnvironment.LOCAL ||\n environment === BenjiConnectEnvironment.DEVELOPMENT ||\n environment === BenjiConnectEnvironment.SANDBOX ||\n environment === BenjiConnectEnvironment.PRODUCTION\n );\n}\n\nexport function mapToConnectEnvironment(\n environment: BenjiConnectEnvironment | string\n): BenjiConnectEnvironment {\n\n if (isBenjiConnectEnvironment(environment)) return environment;\n\n const environments: Record<string, BenjiConnectEnvironment> = {\n local: BenjiConnectEnvironment.LOCAL,\n development: BenjiConnectEnvironment.DEVELOPMENT,\n sandbox: BenjiConnectEnvironment.SANDBOX,\n production: BenjiConnectEnvironment.PRODUCTION,\n };\n const mapped = environments[environment];\n if (mapped) return mapped;\n\n const defaultEnvironment = isLocalHost()\n ? BenjiConnectEnvironment.LOCAL\n : BenjiConnectEnvironment.DEVELOPMENT;\n console.warn(`[Benji Connect SDK] ${environment} not valid environment defaulting to ${defaultEnvironment}`);\n\n return defaultEnvironment;\n}","import {\n BenjiConnectLoginSurface,\n BenjiConnectMode,\n PartnerIntegrationType,\n} from '../types/config';\n\n/**\n * True for the partner-auth LOGIN flows: mode 5 with a real integration type.\n * DUMMY has no partner window, so it keeps the modal surface.\n */\nexport function isNonDummyLogin(\n mode: BenjiConnectMode | undefined,\n authType: PartnerIntegrationType | undefined,\n): boolean {\n return (\n mode === BenjiConnectMode.LOGIN &&\n authType != null &&\n authType !== PartnerIntegrationType.DUMMY\n );\n}\n\n/**\n * Non-DUMMY LOGIN embeds Connect's own button so the click lands in Connect's\n * document; everything else renders the modal overlay. An explicit\n * `login.surface` wins, which is the escape hatch for partners still on the\n * modal.\n */\nexport function resolveLoginSurface(args: {\n mode: BenjiConnectMode | undefined;\n authType: PartnerIntegrationType | undefined;\n configured: BenjiConnectLoginSurface | undefined;\n}): BenjiConnectLoginSurface {\n if (args.configured) return args.configured;\n return isNonDummyLogin(args.mode, args.authType)\n ? BenjiConnectLoginSurface.EMBEDDED_BUTTON\n : BenjiConnectLoginSurface.MODAL;\n}\n\n/** Resolves `login.container` from an element or a document selector. */\nexport function resolveLoginContainer(\n container: HTMLElement | string | undefined,\n): HTMLElement | null {\n if (!container) return null;\n if (typeof container !== 'string') return container;\n try {\n return document.querySelector<HTMLElement>(container);\n } catch {\n console.warn('[Connect SDK] Invalid login.container selector', container);\n return null;\n }\n}\n","/**\n * Anchor-based iframe placement and host DOM application. Naming follows Floating UI /\n * Popper conventions (`bottom-end`, `bottom-start`). Computes layout rects, applies styles\n * to overlay/iframe elements, and manages reposition listeners.\n * @see https://floating-ui.com/docs/computePosition#placement\n */\n\nimport {\n BenjiConnectPlacement,\n type BenjiConnectAnchor,\n type BenjiConnectConfig,\n type BenjiConnectPlacementOffset,\n} from '../types/config';\n\nexport const IFRAME_WIDTH = 400;\nexport const IFRAME_HEIGHT = 645;\n\nconst IFRAME_STATIC_STYLE: CSSStyleDeclaration = {\n border: 'none',\n borderRadius: '20px',\n overflow: 'hidden',\n} as CSSStyleDeclaration;\n\nconst CONTAINER_BASE_STYLE: CSSStyleDeclaration = {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0,0,0,0.5)',\n zIndex: '9999',\n} as CSSStyleDeclaration;\n\nconst VIEWPORT_PADDING = 8;\n\nexport interface IframeRect {\n top: number;\n left: number;\n width: number;\n height: number;\n placement: BenjiConnectPlacement;\n}\n\nexport interface ViewportSize {\n width: number;\n height: number;\n}\n\nexport interface ResolveIframeLayoutOptions {\n warnOnInvalidAnchor?: boolean;\n preserveAnchoredLayout?: IframeRect | null;\n}\n\nfunction isPreservableAnchoredLayout(\n layout: IframeRect | null | undefined,\n): layout is IframeRect {\n return (\n layout != null && layout.placement !== BenjiConnectPlacement.CENTER\n );\n}\n\nfunction clampPreservedAnchoredLayout(\n layout: IframeRect,\n viewport: ViewportSize,\n): IframeRect {\n const maxLeft = viewport.width - layout.width - VIEWPORT_PADDING;\n const maxTop = viewport.height - layout.height - VIEWPORT_PADDING;\n const minLeft = VIEWPORT_PADDING;\n const minTop = VIEWPORT_PADDING;\n\n return {\n ...layout,\n left:\n maxLeft < minLeft\n ? minLeft\n : Math.min(Math.max(layout.left, minLeft), maxLeft),\n top:\n maxTop < minTop\n ? minTop\n : Math.min(Math.max(layout.top, minTop), maxTop),\n };\n}\n\nfunction preservedAnchoredLayoutOrCenter(\n viewport: ViewportSize,\n options: ResolveIframeLayoutOptions,\n): IframeRect {\n const { preserveAnchoredLayout } = options;\n if (isPreservableAnchoredLayout(preserveAnchoredLayout)) {\n return clampPreservedAnchoredLayout(preserveAnchoredLayout, viewport);\n }\n return centerLayout(viewport);\n}\n\nfunction isRefLikeAnchor(\n anchor: BenjiConnectAnchor,\n): anchor is { value: HTMLElement | null | undefined } {\n return (\n typeof anchor === 'object' &&\n anchor !== null &&\n !(anchor instanceof HTMLElement) &&\n 'value' in anchor\n );\n}\n\nexport function resolveAnchor(\n anchor: BenjiConnectAnchor | undefined,\n): HTMLElement | null {\n if (!anchor) {\n return null;\n }\n if (typeof anchor === 'string') {\n return document.querySelector<HTMLElement>(anchor);\n }\n if (typeof anchor === 'function') {\n const resolved = anchor();\n return resolved instanceof HTMLElement ? resolved : null;\n }\n if (isRefLikeAnchor(anchor)) {\n const el = anchor.value;\n return el instanceof HTMLElement ? el : null;\n }\n return anchor instanceof HTMLElement ? anchor : null;\n}\n\nexport function isAnchorVisible(el: HTMLElement): boolean {\n if (!el.isConnected) {\n return false;\n }\n const style = window.getComputedStyle(el);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return false;\n }\n const rect = el.getBoundingClientRect();\n return rect.width > 0 || rect.height > 0;\n}\n\nexport function resolveEffectivePlacement(\n config: Pick<BenjiConnectConfig, 'anchor' | 'placement'>,\n): BenjiConnectPlacement {\n if (!config.anchor) {\n return BenjiConnectPlacement.CENTER;\n }\n return config.placement ?? BenjiConnectPlacement.BOTTOM_END;\n}\n\nexport function defaultOffset(\n offset?: BenjiConnectPlacementOffset,\n): Required<BenjiConnectPlacementOffset> {\n return {\n top: offset?.top ?? 0,\n left: offset?.left ?? 0,\n };\n}\n\nexport function resolveIframeDimensions(viewport: ViewportSize): {\n width: number;\n height: number;\n} {\n const maxW = viewport.width - 2 * VIEWPORT_PADDING;\n const maxH = viewport.height - 2 * VIEWPORT_PADDING;\n const scale = Math.min(1, maxW / IFRAME_WIDTH, maxH / IFRAME_HEIGHT);\n return {\n width: Math.floor(IFRAME_WIDTH * scale),\n height: Math.floor(IFRAME_HEIGHT * scale),\n };\n}\n\nexport function iframeFitsHorizontally(\n viewportWidth: number,\n iframeWidth: number = IFRAME_WIDTH,\n): boolean {\n return viewportWidth >= iframeWidth + 2 * VIEWPORT_PADDING;\n}\n\nfunction centerLayout(viewport: ViewportSize): IframeRect {\n const { width, height } = resolveIframeDimensions(viewport);\n return {\n top: 0,\n left: 0,\n width,\n height,\n placement: BenjiConnectPlacement.CENTER,\n };\n}\n\nexport function fitsBelow(\n anchorBottom: number,\n offsetTop: number,\n viewportHeight: number,\n iframeHeight: number = IFRAME_HEIGHT,\n): boolean {\n const top = anchorBottom + offsetTop;\n const bottom = top + iframeHeight;\n return (\n top >= VIEWPORT_PADDING && bottom <= viewportHeight - VIEWPORT_PADDING\n );\n}\n\nfunction clampHorizontal(left: number, viewportWidth: number): number {\n const min = VIEWPORT_PADDING;\n const max = viewportWidth - IFRAME_WIDTH - VIEWPORT_PADDING;\n if (max < min) {\n return min;\n }\n return Math.min(Math.max(left, min), max);\n}\n\nfunction warnInvalidAnchor(message: string): void {\n console.warn(`[Benji Connect SDK] ${message}`);\n}\n\nexport function computeIframeRect(\n anchorElement: HTMLElement,\n placement: BenjiConnectPlacement,\n offset: BenjiConnectPlacementOffset | undefined,\n viewport: ViewportSize,\n options: ResolveIframeLayoutOptions = {},\n): IframeRect {\n const { warnOnInvalidAnchor = false } = options;\n const resolvedOffset = defaultOffset(offset);\n\n if (placement === BenjiConnectPlacement.CENTER) {\n return centerLayout(viewport);\n }\n\n if (!isAnchorVisible(anchorElement)) {\n if (isPreservableAnchoredLayout(options.preserveAnchoredLayout)) {\n return clampPreservedAnchoredLayout(\n options.preserveAnchoredLayout,\n viewport,\n );\n }\n if (warnOnInvalidAnchor) {\n warnInvalidAnchor(\n 'anchor is hidden or detached; falling back to centered modal',\n );\n }\n return centerLayout(viewport);\n }\n\n const rect = anchorElement.getBoundingClientRect();\n\n if (!fitsBelow(rect.bottom, resolvedOffset.top, viewport.height)) {\n return centerLayout(viewport);\n }\n\n if (!iframeFitsHorizontally(viewport.width)) {\n return centerLayout(viewport);\n }\n\n const top = rect.bottom + resolvedOffset.top;\n const idealLeft =\n placement === BenjiConnectPlacement.BOTTOM_END\n ? rect.right - IFRAME_WIDTH + resolvedOffset.left\n : rect.left + resolvedOffset.left;\n\n if (idealLeft < VIEWPORT_PADDING) {\n if (warnOnInvalidAnchor) {\n warnInvalidAnchor(\n 'anchor rect is unusable for placement; falling back to centered modal',\n );\n }\n return centerLayout(viewport);\n }\n\n const left = clampHorizontal(idealLeft, viewport.width);\n\n return {\n top,\n left,\n width: IFRAME_WIDTH,\n height: IFRAME_HEIGHT,\n placement,\n };\n}\n\nexport function resolveIframeLayout(\n config: BenjiConnectConfig,\n viewport: ViewportSize = {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n options: ResolveIframeLayoutOptions = {},\n): IframeRect {\n const { warnOnInvalidAnchor = true } = options;\n const placement = resolveEffectivePlacement(config);\n const anchorElement = resolveAnchor(config.anchor);\n\n if (\n warnOnInvalidAnchor &&\n placement !== BenjiConnectPlacement.CENTER &&\n !anchorElement\n ) {\n warnInvalidAnchor('anchor not found; falling back to centered modal');\n return preservedAnchoredLayoutOrCenter(viewport, options);\n }\n\n if (placement === BenjiConnectPlacement.CENTER) {\n return centerLayout(viewport);\n }\n\n if (!anchorElement) {\n return preservedAnchoredLayoutOrCenter(viewport, options);\n }\n\n return computeIframeRect(\n anchorElement,\n placement,\n config.offset,\n viewport,\n options,\n );\n}\n\n// --- DOM application ---\n\nexport interface IframeLayoutState {\n layout: IframeRect;\n lastValidAnchoredLayout: IframeRect | null;\n}\n\nexport interface RepositionListenerHandle {\n remove(): void;\n}\n\nexport function applyOverlayBaseStyle(container: HTMLDivElement): void {\n Object.assign(container.style, CONTAINER_BASE_STYLE);\n}\n\nfunction getVisualViewportOffset(): { top: number; left: number } {\n const vv = window.visualViewport;\n if (!vv) {\n return { top: 0, left: 0 };\n }\n return { top: vv.offsetTop, left: vv.offsetLeft };\n}\n\nfunction getRepositionScrollTargets(\n anchor: BenjiConnectAnchor | undefined,\n): Array<Window | HTMLElement> {\n const targets = new Set<Window | HTMLElement>([window]);\n const anchorElement = resolveAnchor(anchor);\n\n if (!anchorElement) {\n return [...targets];\n }\n\n targets.add(anchorElement);\n\n let parent: HTMLElement | null = anchorElement.parentElement;\n while (parent) {\n const { overflow, overflowX, overflowY } = window.getComputedStyle(parent);\n const overflowValue = `${overflow} ${overflowX} ${overflowY}`;\n\n if (/(auto|scroll|overlay)/.test(overflowValue)) {\n targets.add(parent);\n }\n\n parent = parent.parentElement;\n }\n\n return [...targets];\n}\n\nexport function applyIframeLayoutToElements(\n config: BenjiConnectConfig,\n container: HTMLDivElement,\n iframe: HTMLIFrameElement,\n state: IframeLayoutState,\n options: ResolveIframeLayoutOptions = { warnOnInvalidAnchor: false },\n): void {\n state.layout = resolveIframeLayout(config, undefined, {\n ...options,\n preserveAnchoredLayout: state.lastValidAnchoredLayout,\n });\n\n if (state.layout.placement !== BenjiConnectPlacement.CENTER) {\n state.lastValidAnchoredLayout = state.layout;\n }\n\n const iframeStyle = {\n ...IFRAME_STATIC_STYLE,\n width: `${state.layout.width}px`,\n height: `${state.layout.height}px`,\n };\n\n if (state.layout.placement === BenjiConnectPlacement.CENTER) {\n Object.assign(container.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'auto',\n });\n Object.assign(iframe.style, iframeStyle, {\n position: 'relative',\n top: '',\n left: '',\n });\n return;\n }\n\n Object.assign(container.style, {\n display: 'block',\n overflow: 'auto',\n });\n\n const viewportOffset = getVisualViewportOffset();\n Object.assign(iframe.style, iframeStyle, {\n position: 'fixed',\n top: `${state.layout.top + viewportOffset.top}px`,\n left: `${state.layout.left + viewportOffset.left}px`,\n });\n}\n\n/**\n * Embedded LOGIN button: the iframe fills the host's `login.container`, so the\n * host owns the box and the SDK contributes no geometry of its own. `display:\n * block` avoids the inline-element descender gap under the iframe.\n */\nexport function applyEmbeddedIframeStyle(iframe: HTMLIFrameElement): void {\n Object.assign(iframe.style, {\n display: 'block',\n width: '100%',\n height: '100%',\n border: 'none',\n colorScheme: 'normal',\n backgroundColor: 'transparent',\n });\n}\n\nexport function attachRepositionListeners(\n config: Pick<BenjiConnectConfig, 'anchor'>,\n onReposition: () => void,\n): RepositionListenerHandle {\n const repositionHandler = onReposition;\n const repositionScrollTargets = getRepositionScrollTargets(config.anchor);\n repositionScrollTargets.forEach((target) => {\n target.addEventListener('scroll', repositionHandler, { passive: true });\n });\n window.addEventListener('resize', repositionHandler);\n\n const visualViewport = window.visualViewport;\n visualViewport?.addEventListener('resize', repositionHandler);\n visualViewport?.addEventListener('scroll', repositionHandler);\n\n return {\n remove() {\n repositionScrollTargets.forEach((target) => {\n target.removeEventListener('scroll', repositionHandler);\n });\n window.removeEventListener('resize', repositionHandler);\n visualViewport?.removeEventListener('resize', repositionHandler);\n visualViewport?.removeEventListener('scroll', repositionHandler);\n },\n };\n}\n","/**\n * LOGIN query params on the embedded Connect button iframe. Lockstep with\n * Benji Connect `src/constants/login.ts`, which reads them in `login-button.ts`.\n */\nexport const LOGIN_BUTTON_QUERY_KEYS = {\n connectToken: 'connect_token',\n configToken: 'config_token',\n partnerAuthLink: 'partner_auth_link',\n windowTarget: 'login_window_target',\n buttonText: 'login_button_text',\n} as const;\n\n/**\n * Benji Connect serves the button from its own lightweight Vite entry rather\n * than the SPA root, so it boots without Pinia, the router, or analytics.\n */\nexport const LOGIN_BUTTON_PATH = '/login-button.html';\n","import { BenjiConnectAuthAction } from \"./auth\";\n\n// Known event names coming from the SDK transport (postMessage)\nexport enum BenjiConnectEventType {\n AUTH_SUCCESS = 'AUTH_SUCCESS',\n FLOW_EXIT = 'FLOW_EXIT',\n FLOW_SUCCESS = 'FLOW_SUCCESS',\n EVENT = 'EVENT',\n ERROR = 'ERROR',\n /** LOGIN embedded button: Connect resolved the partner auth link and rendered the button. */\n LOGIN_READY = 'LOGIN_READY',\n /**\n * LOGIN embedded button: Connect painted themed chrome (not session-ready).\n * Requires Benji Connect [BEN-2572] to emit this from the login-button entry;\n * the iframe does not send it until Connect is deployed.\n */\n LOGIN_DISPLAYED = 'LOGIN_DISPLAYED',\n /** LOGIN embedded button: pointer or focus entered the in-iframe button. */\n LOGIN_HOVER = 'LOGIN_HOVER',\n /** LOGIN embedded button: the button was pressed, before the partner tab opens. */\n LOGIN_CLICKED = 'LOGIN_CLICKED',\n}\n\n// Known exit trigger types coming from the SDK transport (postMessage)\nexport enum BenjiConnectExitTrigger {\n ACTION_BUTTON_CLICKED = 'ACTION_BUTTON_CLICKED',\n BACK_TO_MERCHANT_CLICKED = 'BACK_TO_MERCHANT_CLICKED', // deprecated\n CLOSE_BUTTON_CLICKED = 'CLOSE_BUTTON_CLICKED',\n TAPPED_OUT_OF_BOUNDS = 'TAPPED_OUT_OF_BOUNDS',\n /** SDK-detected partner-auth window loss (not a Connect UI close click). */\n WINDOW_CLOSE_DETECTED = 'WINDOW_CLOSE_DETECTED',\n /** @deprecated Use WINDOW_CLOSE_DETECTED. Same meaning; no longer emitted by this SDK version. */\n POPUP_CLOSED = 'POPUP_CLOSED',\n}\n\nexport enum BenjiConnectErrorName {\n UNEXPECTED_ERROR = 'unexpected_error',\n PARTNER_CONNECT_ERROR = 'partner_connect_error'\n}\n\nexport type BenjiConnectErrorID = '400' | '500'; // Placeholders for now\n\n// Transport-layer token (raw, unprocessed from postMessage)\nexport interface BenjiConnectEventToken {\n access_token?: string;\n refresh_token?: string;\n expires_at?: string | number;\n exchange_token?: string;\n}\n\nexport interface BenjiConnectEventUserData {\n user: {\n id: number\n first_name: string\n last_name: string\n uuid?: string\n }\n status: BenjiConnectEventUserStatusData\n extra_data?: {\n total_rewards_earned?: number\n total_rewards_redeemed?: number\n created_date?: string\n }\n}\n\nexport interface BenjiConnectEventTransactionData {\n action: string;\n amount: number;\n trigger_event_id: string;\n trigger_name: string;\n}\n\nexport interface BenjiConnectEventUserStatusData {\n status_id: string\n num_of_rewards: number\n reward_status: string\n partner_status_tier_id?: number\n}\n\n// Basic structure for Benji Connect SDK typed events\nexport interface BenjiConnectEvent {\n type: BenjiConnectEventType;\n data?: BenjiConnectEventData;\n}\n\nexport interface BenjiConnectEventData {\n [k: string]: unknown;\n}\n\nexport interface BenjiConnectEventMessage<K extends BenjiConnectEventType = BenjiConnectEventType> {\n type: K; // discriminant\n data: BenjiConnectEventDataMap[K];\n}\n\nexport interface BenjiConnectAuthSuccessEventData {\n action: BenjiConnectAuthAction;\n metadata?: BenjiConnectEventUserData;\n token?: BenjiConnectEventToken,\n transaction?: BenjiConnectEventTransactionData;\n}\n\nexport interface BenjiConnectFlowExitEventData {\n step: string;\n trigger: BenjiConnectExitTrigger;\n}\n\nexport interface BenjiConnectErrorEventData {\n error: Error;\n}\n\n/** LOGIN embedded-button lifecycle events carry no payload of their own. */\nexport type BenjiConnectLoginButtonEventData = Record<string, never>;\n\n// Canonical event map \nexport type BenjiConnectEventDataMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: BenjiConnectAuthSuccessEventData;\n [BenjiConnectEventType.FLOW_EXIT]: BenjiConnectFlowExitEventData;\n [BenjiConnectEventType.FLOW_SUCCESS]: BenjiConnectAuthSuccessEventData;\n [BenjiConnectEventType.EVENT]: BenjiConnectEventData;\n [BenjiConnectEventType.ERROR]: BenjiConnectErrorEventData;\n [BenjiConnectEventType.LOGIN_READY]: BenjiConnectLoginButtonEventData;\n [BenjiConnectEventType.LOGIN_DISPLAYED]: BenjiConnectLoginButtonEventData;\n [BenjiConnectEventType.LOGIN_HOVER]: BenjiConnectLoginButtonEventData;\n [BenjiConnectEventType.LOGIN_CLICKED]: BenjiConnectLoginButtonEventData;\n\n // Optional catch-all fan-out\n '*': { type: BenjiConnectEventType; data: BenjiConnectEventDataMap[BenjiConnectEventType] };\n};","import { BenjiConnectAuthToken } from '../types/auth';\nimport { BenjiConnectEventToken, BenjiConnectEventType } from '../types/event';\n\nconst CONNECT_MESSAGE_TYPES = new Set<string>(Object.values(BenjiConnectEventType));\n\nexport function isConnectMessageType(data: unknown): boolean {\n if (!data || typeof data !== 'object') return false;\n const type = (data as { type?: string }).type;\n return typeof type === 'string' && CONNECT_MESSAGE_TYPES.has(type);\n}\n\nexport const extractAccessToken = (token?: BenjiConnectEventToken | string): string =>\n typeof token === 'string' ? token : (token?.access_token ?? '');\n\nexport const extractExchangeToken = (token?: BenjiConnectEventToken | string): string =>\n typeof token === 'string' ? token : (token?.exchange_token ?? '');\n\nexport const mapEventToConnectToken = (data?: BenjiConnectEventToken): BenjiConnectAuthToken => ({\n access_token: data?.access_token ?? '',\n refresh_token: data?.refresh_token ?? '',\n expires_at: data?.expires_at ?? ''\n});\n","import { BenjiConnectEventUserData } from \"../types/event\";\nimport { BenjiConnectUserData } from \"../types/user\";\n\nexport function isConnectUserData (\n input: BenjiConnectUserData | Record<string, any>\n): boolean {\n if (!input) return false;\n const data = mapEventToConnectUserData(input);\n if (data.user.id != 0) return true;\n return false;\n}\n\nexport const mapEventToConnectUserData = (\n data?: BenjiConnectEventUserData | Record<string, any>\n): BenjiConnectUserData => ({\n user: {\n id: data?.user?.id ?? 0,\n first_name: data?.user?.first_name ?? '',\n last_name: data?.user?.last_name ?? '',\n uuid: data?.user?.uuid \n },\n status: {\n status_id: data?.status?.status_id ?? '',\n num_of_rewards: data?.status?.num_of_rewards ?? 0,\n reward_status: data?.status?.reward_status ?? '',\n partner_status_tier_id: data?.status?.partner_status_tier_id\n },\n extra_data: {\n total_rewards_earned: data?.extra_data?.total_rewards_earned,\n total_rewards_redeemed: data?.extra_data?.total_rewards_redeemed,\n created_date: data?.extra_data?.created_date\n }\n});\n","import { BenjiConnectEventTransactionData } from \"../types/event\";\nimport { BenjiConnectTransactionData } from \"../types/transaction\";\n\nexport const mapEventToConnectTransactionData = (data?: BenjiConnectEventTransactionData): BenjiConnectTransactionData | null => {\n if (!data) return null;\n return {\n action: data.action,\n amount: data.amount,\n trigger_event_id: data.trigger_event_id,\n trigger_name: data.trigger_name\n };\n}","import {\n BenjiConnectLoginSurface,\n BenjiConnectMetadata,\n BenjiConnectMode,\n BenjiConnectOnErrorData,\n BenjiConnectOnEventData,\n BenjiConnectOnExitData,\n BenjiConnectOnExitMetadata,\n BenjiConnectOnSuccessData,\n BenjiConnectOnSuccessMetadata,\n} from './config';\n\nimport { \n extractAccessToken,\n extractExchangeToken,\n mapEventToConnectToken \n} from '../utils/auth';\n\nimport { BenjiConnectAuthAction } from './auth';\n\nimport { buildContext } from '../utils/config';\nimport { mapEventToConnectUserData } from '../utils/user';\n\nimport { \n BenjiConnectAuthSuccessEventData,\n BenjiConnectErrorEventData, \n BenjiConnectEventDataMap, \n BenjiConnectEventMessage, \n BenjiConnectEventType, \n BenjiConnectFlowExitEventData\n} from './event';\nimport { mapEventToConnectTransactionData } from '../utils/transaction';\n\nexport type MessageRouterContext = {\n iframe: HTMLIFrameElement | null;\n mode: BenjiConnectMode;\n surface: BenjiConnectLoginSurface;\n};\n\nexport type MessageRouterConfig = {\n onSuccess?: (\n token: string, \n metadata: BenjiConnectOnSuccessMetadata\n ) => void;\n onError?: (\n error: Error,\n error_id: string,\n metadata: BenjiConnectMetadata\n ) => void;\n onExit?: (\n metadata: BenjiConnectOnExitMetadata\n ) => void;\n onEvent?: (\n type: BenjiConnectEventType, \n metadata: BenjiConnectMetadata\n ) => void;\n onLoginDisplayed?: () => void;\n onLoginReady?: () => void;\n onLoginHover?: () => void;\n onLoginClicked?: () => void;\n close?: () => void;\n};\n\nexport const mapToAuthSuccessData = (\n message: BenjiConnectEventMessage<BenjiConnectEventType.AUTH_SUCCESS>,\n data: BenjiConnectAuthSuccessEventData\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n action: data.action,\n token: mapEventToConnectToken(data.token),\n transactionData: mapEventToConnectTransactionData(data.transaction),\n userData: mapEventToConnectUserData(data.metadata)\n }\n };\n};\n\nexport const mapToOnExitData = (data: BenjiConnectFlowExitEventData): BenjiConnectOnExitData => {\n return {\n metadata: {\n context: buildContext(),\n step: data.step,\n trigger: data.trigger\n }\n };\n};\n\nexport const mapToOnSuccessData = (data: BenjiConnectAuthSuccessEventData): BenjiConnectOnSuccessData => {\n \n const token = data.action === BenjiConnectAuthAction.Login\n ? extractExchangeToken(data.token)\n : extractAccessToken(data.token);\n\n let metadata: BenjiConnectOnSuccessMetadata = {\n context: buildContext(),\n action: data.action,\n user_data: data.metadata\n };\n\n if (data.transaction) {\n metadata.transaction_data = data.transaction;\n }\n \n return { token, metadata };\n};\n\nexport const mapToOnErrorData = (data: BenjiConnectErrorEventData): BenjiConnectOnErrorData => {\n return {\n error: data.error,\n error_id: '500', // Placeholder\n metadata: {\n context: buildContext()\n }\n };\n};\n\nexport const mapToOnEventData = <K extends BenjiConnectEventType>(\n message: BenjiConnectEventMessage<K>,\n data: BenjiConnectEventDataMap[K]\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n ...data\n }\n };\n};\n\n/**\n * LOGIN embedded-button lifecycle. Payload-free, so the mapper only stamps\n * context — but it goes through a mapper like every other inbound event rather\n * than being built inline in `MessageRouter`.\n */\nexport const mapToLoginButtonEventData = <\n K extends\n | BenjiConnectEventType.LOGIN_READY\n | BenjiConnectEventType.LOGIN_DISPLAYED\n | BenjiConnectEventType.LOGIN_HOVER\n | BenjiConnectEventType.LOGIN_CLICKED,\n>(\n message: BenjiConnectEventMessage<K>,\n _data: BenjiConnectEventDataMap[K],\n): BenjiConnectOnEventData => {\n return {\n type: message.type,\n metadata: {\n context: buildContext(),\n },\n };\n};\n\nexport type BenjiConnectCallbackDataMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: BenjiConnectOnEventData;\n [BenjiConnectEventType.FLOW_EXIT]: BenjiConnectOnExitData;\n [BenjiConnectEventType.FLOW_SUCCESS]: BenjiConnectOnSuccessData;\n [BenjiConnectEventType.ERROR]: BenjiConnectOnErrorData;\n [BenjiConnectEventType.EVENT]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_READY]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_DISPLAYED]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_HOVER]: BenjiConnectOnEventData;\n [BenjiConnectEventType.LOGIN_CLICKED]: BenjiConnectOnEventData;\n '*': BenjiConnectOnEventData;\n};\n\nexport const BenjiConnectCallbackMapperMap = {\n [BenjiConnectEventType.AUTH_SUCCESS]: mapToAuthSuccessData,\n [BenjiConnectEventType.FLOW_EXIT]: mapToOnExitData,\n [BenjiConnectEventType.FLOW_SUCCESS]: mapToOnSuccessData,\n [BenjiConnectEventType.ERROR]: mapToOnErrorData,\n [BenjiConnectEventType.EVENT]: mapToOnEventData,\n [BenjiConnectEventType.LOGIN_READY]: mapToLoginButtonEventData,\n [BenjiConnectEventType.LOGIN_DISPLAYED]: mapToLoginButtonEventData,\n [BenjiConnectEventType.LOGIN_HOVER]: mapToLoginButtonEventData,\n [BenjiConnectEventType.LOGIN_CLICKED]: mapToLoginButtonEventData,\n} as const;\n\n","import { \n Endpoints\n} from '../config';\n\nimport { BenjiConnectLoginSurface, BenjiConnectMode } from '../types/config';\nimport {\n BenjiConnectEventType,\n type BenjiConnectEventMessage,\n} from '../types/event';\n\nimport type {\n BenjiConnectOnSuccessData,\n BenjiConnectOnExitData,\n} from '../types/config';\nimport type { BenjiConnectHostMessage } from '../types/host';\n\nimport {\n BenjiConnectCallbackMapperMap,\n MessageRouterConfig,\n mapToOnEventData,\n type MessageRouterContext,\n} from '../types/router';\nimport { isConnectMessageType } from '../utils/auth';\n\n/**\n * Host ↔ Benji Connect transport. Connect owns the partner-auth window, so this\n * router never forwards partner traffic: every message it accepts comes from the\n * Connect iframe on the Connect origin, and every message it sends goes back to\n * that same iframe.\n *\n * One router per `ConnectSDK`, deliberately. A LOGIN page mounts a button per\n * call to action, so several Connect frames post to the same host window at\n * once; a shared router would hand every frame's events to whichever instance\n * registered last, and tearing one button down would silence the rest. Each\n * router therefore keeps its own listener and answers only to its own frame —\n * see `isFromOwnFrame`.\n */\nexport class MessageRouter {\n\n private config: MessageRouterConfig = {};\n private iframe: HTMLIFrameElement | null = null;\n private mode: BenjiConnectMode = BenjiConnectMode.CONNECT;\n private surface: BenjiConnectLoginSurface = BenjiConnectLoginSurface.MODAL;\n private connectOrigin = '';\n private configuredListeners = false;\n\n configureMessageRouter(config: MessageRouterConfig) {\n this.config = config;\n }\n\n setContext(context: MessageRouterContext) {\n this.iframe = context.iframe;\n this.mode = context.mode;\n this.surface = context.surface;\n this.connectOrigin = new URL(Endpoints.benji_connect_auth_url).origin;\n }\n\n setMode(mode: BenjiConnectMode) {\n this.mode = mode;\n }\n\n /** Host → Connect iframe. Always origin-targeted; never `'*'`. */\n postToConnect(message: BenjiConnectHostMessage): boolean {\n const iframeWindow = this.iframe?.contentWindow ?? null;\n if (!iframeWindow) {\n console.warn('[Benji Connect SDK] Cannot post to Connect, no iframe mounted', message.type);\n return false;\n }\n\n const targetOrigin =\n this.connectOrigin || new URL(Endpoints.benji_connect_auth_url).origin;\n iframeWindow.postMessage(message, targetOrigin);\n return true;\n }\n\n private errorEventHandler = (event: Event) => {\n return this.handleErrorMessage(event);\n };\n\n private messageEventHandler = (event: MessageEvent<unknown>) => {\n return this.handleMessage(event);\n };\n\n addEventListeners() {\n if (this.configuredListeners) return;\n window.addEventListener('error', this.errorEventHandler);\n window.addEventListener('unhandledrejection', this.errorEventHandler);\n window.addEventListener('message', this.messageEventHandler);\n this.configuredListeners = true;\n }\n\n removeEventListeners() {\n window.removeEventListener('error', this.errorEventHandler);\n window.removeEventListener('unhandledrejection', this.errorEventHandler);\n window.removeEventListener('message', this.messageEventHandler);\n this.configuredListeners = false;\n this.iframe = null;\n this.mode = BenjiConnectMode.CONNECT;\n this.surface = BenjiConnectLoginSurface.MODAL;\n this.connectOrigin = '';\n }\n\n handleErrorMessage(event: Event) { \n switch(event.type) {\n case 'error':\n case 'unhandledrejection': {\n break;\n }\n default: {\n console.error('[Benji Connect SDK] Received Unknown error message', event);\n break;\n }\n }\n }\n\n /**\n * The origin check alone is not enough when the page hosts several Connect\n * frames: they all share it. Matching the source window is what keeps a hover\n * on one button from being reported as a hover on another.\n */\n private isFromOwnFrame(event: MessageEvent<unknown>): boolean {\n const iframeWindow = this.iframe?.contentWindow ?? null;\n if (!iframeWindow) return false;\n return event.source === iframeWindow;\n }\n\n handleMessage(event: MessageEvent<unknown>) {\n if (!isConnectMessageType(event.data)) return;\n\n const expectedOrigin: string = new URL(Endpoints.benji_connect_auth_url).origin;\n if (!event || event.origin !== expectedOrigin) {\n console.warn('[Benji Connect SDK] Skipped message, received event from unexpected origin', event.origin, expectedOrigin);\n return;\n }\n\n if (!this.isFromOwnFrame(event)) return;\n\n const raw = event.data;\n if (!raw || typeof raw !== 'object') return;\n\n const partial = raw as Partial<BenjiConnectEventMessage>;\n if (typeof partial.type !== 'string') return;\n \n const message = partial as BenjiConnectEventMessage;\n\n switch (message.type) {\n\n case BenjiConnectEventType.AUTH_SUCCESS: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.AUTH_SUCCESS>;\n const callbackData = BenjiConnectCallbackMapperMap.AUTH_SUCCESS(connectMessage, connectMessage.data);\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.FLOW_EXIT: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.FLOW_EXIT>;\n const callbackData = BenjiConnectCallbackMapperMap.FLOW_EXIT(connectMessage.data) as BenjiConnectOnExitData;\n this.config.onExit?.(callbackData.metadata);\n // Embedded button: Connect returns to ready after window loss and\n // posts FLOW_EXIT as a host toast. Unmounting would remove the retry\n // surface. Hosts that want the button gone still call close().\n if (this.surface !== BenjiConnectLoginSurface.EMBEDDED_BUTTON) {\n this.config.close?.();\n }\n break;\n }\n\n case BenjiConnectEventType.FLOW_SUCCESS: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.FLOW_SUCCESS>;\n const callbackData = BenjiConnectCallbackMapperMap.FLOW_SUCCESS(connectMessage.data) as BenjiConnectOnSuccessData;\n this.config.onSuccess?.(callbackData.token, callbackData.metadata);\n // Terminal: the exchange finished. Unlike FLOW_EXIT on the embedded\n // button, this session is done.\n if (this.mode === BenjiConnectMode.LOGIN) {\n this.config.close?.();\n }\n break;\n }\n\n case BenjiConnectEventType.ERROR: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.ERROR>;\n const callbackData = BenjiConnectCallbackMapperMap.ERROR(connectMessage.data);\n this.config.onError?.(callbackData.error, callbackData.error_id, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.EVENT: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.EVENT>;\n const callbackData = mapToOnEventData(connectMessage, connectMessage.data);\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_READY: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_READY>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_READY(connectMessage, connectMessage.data);\n this.config.onLoginReady?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_DISPLAYED: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_DISPLAYED>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_DISPLAYED(connectMessage, connectMessage.data);\n this.config.onLoginDisplayed?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_HOVER: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_HOVER>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_HOVER(connectMessage, connectMessage.data);\n this.config.onLoginHover?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n case BenjiConnectEventType.LOGIN_CLICKED: {\n const connectMessage = message as BenjiConnectEventMessage<BenjiConnectEventType.LOGIN_CLICKED>;\n const callbackData = BenjiConnectCallbackMapperMap.LOGIN_CLICKED(connectMessage, connectMessage.data);\n this.config.onLoginClicked?.();\n this.config.onEvent?.(callbackData.type, callbackData.metadata);\n break;\n }\n\n default: {\n const _exhaustive: never = message.type;\n console.warn('[Benji Connect SDK] Unhandled connect message type', _exhaustive);\n break;\n }\n\n }\n }\n\n}\n","import type { BenjiConnectLoginButtonTheme } from '../types/config';\nimport type { BenjiConnectLoginButtonThemeWire } from '../types/host';\n\nconst WIRE_KEYS: {\n [K in keyof BenjiConnectLoginButtonTheme]-?: keyof BenjiConnectLoginButtonThemeWire;\n} = {\n background: 'background',\n backgroundHover: 'background_hover',\n backgroundDisabled: 'background_disabled',\n text: 'text',\n textDisabled: 'text_disabled',\n border: 'border',\n borderWidth: 'border_width',\n borderRadius: 'border_radius',\n fontFamily: 'font_family',\n fontSize: 'font_size',\n fontWeight: 'font_weight',\n lineHeight: 'line_height',\n textTransform: 'text_transform',\n};\n\nexport function toWireLoginButtonTheme(\n theme: BenjiConnectLoginButtonTheme | undefined,\n): BenjiConnectLoginButtonThemeWire | undefined {\n if (!theme) return undefined;\n\n const wire: BenjiConnectLoginButtonThemeWire = {};\n let hasValue = false;\n\n (Object.keys(WIRE_KEYS) as (keyof BenjiConnectLoginButtonTheme)[]).forEach(\n (key) => {\n const value = theme[key];\n if (value == null || value === '') return;\n wire[WIRE_KEYS[key]] = value;\n hasValue = true;\n },\n );\n\n return hasValue ? wire : undefined;\n}\n","/// <reference path=\"./global.d.ts\" />\n\nimport { \n configureConfig, \n Endpoints,\n} from './config';\n\nimport { \n type BenjiConnectConfig,\n type BenjiConnectConfigUpdate,\n BenjiConnectEnvironment,\n BenjiConnectLoginSurface,\n BenjiConnectLoginWindowTarget,\n BenjiConnectMode,\n BenjiConnectPlacement,\n PartnerIntegrationType,\n} from './types/config';\n\nimport { \n buildContext, \n mapToConnectEnvironment \n} from './utils/config';\n\nimport {\n resolveLoginContainer,\n resolveLoginSurface,\n} from './utils/loginSurface';\n\nimport {\n IFRAME_HEIGHT,\n IFRAME_WIDTH,\n applyEmbeddedIframeStyle,\n applyIframeLayoutToElements,\n applyOverlayBaseStyle,\n attachRepositionListeners,\n type IframeLayoutState,\n type RepositionListenerHandle,\n} from './utils/placement';\n\nimport { LOGIN_BUTTON_PATH, LOGIN_BUTTON_QUERY_KEYS } from './constants/login';\nimport { MessageRouter } from './router/message';\nimport { BenjiConnectExitTrigger } from './types/event';\nimport { BenjiConnectHostMessageType } from './types/host';\nimport { toWireLoginButtonTheme } from './utils/loginButtonTheme';\n\nclass ConnectSDK {\n\n private sdkConfig: BenjiConnectConfig;\n private iframe: HTMLIFrameElement | null = null;\n private container: HTMLDivElement | null = null;\n private layoutState: IframeLayoutState = {\n layout: {\n top: 0,\n left: 0,\n width: IFRAME_WIDTH,\n height: IFRAME_HEIGHT,\n placement: BenjiConnectPlacement.CENTER,\n },\n lastValidAnchoredLayout: null,\n };\n private repositionListeners: RepositionListenerHandle | null = null;\n private isClosing = false;\n\n /**\n * One router per instance: a LOGIN page mounts a button per call to action, so\n * the routers must not share callbacks, a frame reference, or a listener.\n */\n private readonly router = new MessageRouter();\n\n private onIframeLoad = (): void => {\n if (this.isClosing || !this.iframe) return;\n this.postHostConfig();\n };\n\n private postHostConfig(): void {\n if (!this.iframe) return;\n const login_button_theme = toWireLoginButtonTheme(\n this.sdkConfig.login?.buttonTheme,\n );\n const login_button_text = this.sdkConfig.login?.buttonText;\n const connectToken = this.sdkConfig.token?.trim();\n const configToken = this.sdkConfig.tokenData?.configToken?.trim();\n const partnerAuthLink = this.sdkConfig.tokenData?.partnerAuthLink?.trim();\n this.router.postToConnect({\n type: BenjiConnectHostMessageType.HOST_CONFIG_UPDATE,\n data: {\n ...(connectToken ? { connect_token: connectToken } : {}),\n ...(configToken ? { config_token: configToken } : {}),\n ...(partnerAuthLink ? { partner_auth_link: partnerAuthLink } : {}),\n ...(login_button_theme ? { login_button_theme } : {}),\n ...(login_button_text !== undefined\n ? { login_button_text: login_button_text.trim() }\n : {}),\n },\n });\n }\n\n constructor(config: BenjiConnectConfig) {\n\n this.sdkConfig = config;\n\n // Validations\n if (!this.sdkConfig.environment) throw new Error('Environment is required');\n\n // Set internal config for environment based on consumer input at runtime\n const environment: BenjiConnectEnvironment = mapToConnectEnvironment(this.sdkConfig.environment);\n this.sdkConfig.environment = environment;\n configureConfig(environment);\n\n const connectToken = this.sdkConfig.token?.trim();\n if (!connectToken && !this.isEmbeddedButton()) {\n throw new Error('Connect token is required');\n }\n }\n\n private resolveAuthType(): PartnerIntegrationType | undefined {\n return this.sdkConfig.tokenData?.authType ?? this.sdkConfig.authType;\n }\n\n private resolveMode(): BenjiConnectMode {\n return this.sdkConfig.mode ?? BenjiConnectMode.CONNECT;\n }\n\n private resolveSurface(): BenjiConnectLoginSurface {\n return resolveLoginSurface({\n mode: this.resolveMode(),\n authType: this.resolveAuthType(),\n configured: this.sdkConfig.login?.surface,\n });\n }\n\n private isEmbeddedButton(): boolean {\n return this.resolveSurface() === BenjiConnectLoginSurface.EMBEDDED_BUTTON;\n }\n\n private resolveLoginWindowTarget(): BenjiConnectLoginWindowTarget {\n return (\n this.sdkConfig.login?.windowTarget ?? BenjiConnectLoginWindowTarget.TAB\n );\n }\n\n private isSessionActive(): boolean {\n return this.iframe != null;\n }\n\n initialize() {\n this.router.configureMessageRouter({\n onSuccess: this.sdkConfig.onSuccess,\n onError: this.sdkConfig.onError,\n onExit: this.sdkConfig.onExit,\n onEvent: this.sdkConfig.onEvent,\n onLoginDisplayed: this.sdkConfig.onLoginDisplayed,\n onLoginReady: this.sdkConfig.onLoginReady,\n onLoginHover: this.sdkConfig.onLoginHover,\n onLoginClicked: this.sdkConfig.onLoginClicked,\n close: () => this.close(),\n });\n\n // TODO: Tracker.configureWithOptions(sdkOptions);\n // TODO: Tracker.trackSDKInitialized();\n }\n\n async open() {\n if (this.isSessionActive()) return;\n\n this.initialize();\n this.router.setMode(this.resolveMode());\n this.openUI();\n // Listeners attach only after a frame exists. A missing login.container\n // reports through onError and returns without an iframe — attaching first\n // would leak window listeners that cleanup used to skip.\n if (!this.iframe) return;\n this.router.addEventListeners();\n // TODO: Track SDK Opened Tracker.trackSDKOpened();\n }\n\n /**\n * Hands the mounted iframe a refreshed connect token so a long-lived host page\n * does not go stale, without remounting and losing the resolved auth link.\n */\n updateConfig(update: BenjiConnectConfigUpdate): void {\n if (update.token) this.sdkConfig.token = update.token;\n if (update.tokenData) {\n this.sdkConfig.tokenData = {\n ...this.sdkConfig.tokenData,\n ...update.tokenData,\n };\n }\n if (update.login) {\n this.sdkConfig.login = {\n ...this.sdkConfig.login,\n ...update.login,\n ...(update.login.buttonTheme\n ? {\n buttonTheme: {\n ...this.sdkConfig.login?.buttonTheme,\n ...update.login.buttonTheme,\n },\n }\n : {}),\n };\n }\n\n this.postHostConfig();\n }\n\n private syncContext(): void {\n this.router.setContext({\n iframe: this.iframe,\n mode: this.resolveMode(),\n surface: this.resolveSurface(),\n });\n }\n\n private buildIframeUrl(): string {\n const embedded = this.isEmbeddedButton();\n const url = new URL(\n embedded ? LOGIN_BUTTON_PATH : '',\n Endpoints.benji_connect_auth_url,\n );\n const connectToken = this.sdkConfig.token?.trim();\n if (connectToken) {\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.connectToken, connectToken);\n }\n url.searchParams.set('t', String(Date.now()));\n if (this.sdkConfig.mode != null) {\n url.searchParams.set('mode', String(this.sdkConfig.mode));\n }\n\n if (!embedded) return url.toString();\n\n // Connect owns window.open, so it needs the auth link, its OAuth state\n // nonce, and the shell choice up front — resolved at load, long before any\n // click, which is what removes the bootstrap race.\n url.searchParams.set(\n LOGIN_BUTTON_QUERY_KEYS.windowTarget,\n this.resolveLoginWindowTarget(),\n );\n const buttonText = this.sdkConfig.login?.buttonText?.trim();\n if (buttonText) {\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.buttonText, buttonText);\n }\n const { configToken, partnerAuthLink } = this.sdkConfig.tokenData ?? {};\n if (configToken) {\n url.searchParams.set(LOGIN_BUTTON_QUERY_KEYS.configToken, configToken);\n }\n if (partnerAuthLink) {\n url.searchParams.set(\n LOGIN_BUTTON_QUERY_KEYS.partnerAuthLink,\n partnerAuthLink,\n );\n }\n return url.toString();\n }\n\n openUI() {\n if (this.iframe) return;\n\n const embedded = this.isEmbeddedButton();\n const host = embedded\n ? resolveLoginContainer(this.sdkConfig.login?.container)\n : null;\n\n if (embedded && !host) {\n // No iframe, so open() must not attach window listeners. cleanup()\n // always runs close(), which can tear listeners down if a later\n // change reorders that again.\n console.warn('[Connect SDK] login.container is required for the embedded LOGIN button');\n this.sdkConfig.onError?.(\n new Error('Sign-in could not be started.'),\n '400',\n { context: buildContext() },\n );\n return;\n }\n\n this.iframe = document.createElement('iframe');\n // Bind the router before `src` so iframe `load` can post HOST_CONFIG_UPDATE\n // (theme + tokens) once Connect's listener is up.\n this.syncContext();\n this.iframe.addEventListener('load', this.onIframeLoad);\n this.iframe.src = this.buildIframeUrl();\n\n if (embedded && host) {\n this.iframe.title = 'Sign in';\n applyEmbeddedIframeStyle(this.iframe);\n host.appendChild(this.iframe);\n return;\n }\n\n this.container = document.createElement('div');\n applyOverlayBaseStyle(this.container);\n this.container.appendChild(this.iframe);\n document.body.appendChild(this.container);\n\n applyIframeLayoutToElements(\n this.sdkConfig,\n this.container,\n this.iframe,\n this.layoutState,\n { warnOnInvalidAnchor: true },\n );\n this.repositionListeners = attachRepositionListeners(\n this.sdkConfig,\n () => {\n if (!this.iframe || !this.container) return;\n applyIframeLayoutToElements(\n this.sdkConfig,\n this.container,\n this.iframe,\n this.layoutState,\n );\n },\n );\n\n this.container.addEventListener('click', (e) => {\n if (e.target === this.container) {\n // Trigger exit when user taps outside modal bounds\n this.sdkConfig.onExit?.({\n context: buildContext(),\n trigger: BenjiConnectExitTrigger.TAPPED_OUT_OF_BOUNDS\n });\n this.close();\n }\n });\n }\n\n close() {\n this.isClosing = true;\n this.router.removeEventListeners();\n\n if (!this.iframe) {\n this.isClosing = false;\n return;\n }\n\n this.repositionListeners?.remove();\n this.repositionListeners = null;\n this.layoutState.lastValidAnchoredLayout = null;\n\n this.iframe.removeEventListener('load', this.onIframeLoad);\n\n // Embedded buttons mount straight into the host's container, so there is no\n // SDK-owned overlay to detach.\n const mountedNode = this.container ?? this.iframe;\n if (mountedNode.parentNode) {\n mountedNode.parentNode.removeChild(mountedNode);\n }\n this.iframe = null;\n this.container = null;\n this.isClosing = false;\n }\n\n cleanup() {\n // Always tear down: close() removes window listeners even when no\n // iframe was mounted (a failed open used to leak them).\n this.close();\n }\n\n ping() { return 'pong'; }\n}\n\nexport default ConnectSDK;\n","/// <reference path=\"./global.d.ts\" />\nimport ConnectSDK from './connect-sdk';\n(globalThis as any).ConnectSDK = ConnectSDK;"],"mappings":"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","names":["endpoints","project_environment","endpoints","project_environment","endpoints","project_environment","BenjiConnectEventType","data","data","data","data","_a","_b"]}