@burdenoff/microfe-brainyrich 2026.830.2 → 2026.1025.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plaidLink.js","names":[],"sources":["../../../src/brainyrich/utils/plaidLink.ts"],"sourcesContent":["/**\n * Plaid Link loader (BOFF-4234).\n *\n * Plaid requires Link to be loaded from its own CDN (it is not distributed as\n * an npm bundle that may be self-hosted), so the script is injected once, on\n * demand, the first time a user starts linking an institution. Nothing is\n * loaded for users who never click \"Link an institution\".\n *\n * The flow this wraps:\n * 1. the backend mints a short-lived `link_token` (`braCreatePlaidLinkToken`)\n * 2. Plaid Link runs the bank's own consent + login screens in its iframe —\n * bank credentials never touch BrainyRich\n * 3. on success Plaid hands back a one-time `public_token`, which the\n * backend exchanges server-side (`braExchangePlaidPublicToken`)\n */\n\nexport const PLAID_LINK_SCRIPT_URL = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';\n\nexport interface PlaidLinkSuccessMetadata {\n institution?: { institution_id?: string | null; name?: string | null } | null;\n}\n\nexport interface PlaidLinkExitError {\n error_code?: string;\n error_message?: string;\n display_message?: string | null;\n}\n\ninterface PlaidLinkHandler {\n open: () => void;\n exit: (options?: { force?: boolean }) => void;\n destroy: () => void;\n}\n\ninterface PlaidLinkCreateOptions {\n token: string;\n onSuccess: (publicToken: string, metadata: PlaidLinkSuccessMetadata) => void;\n onExit?: (error: PlaidLinkExitError | null) => void;\n}\n\ninterface PlaidGlobal {\n create: (options: PlaidLinkCreateOptions) => PlaidLinkHandler;\n}\n\ntype WindowWithPlaid = Window & { Plaid?: PlaidGlobal };\n\nlet loader: Promise<PlaidGlobal> | null = null;\n\n/** Load Plaid Link once per page; concurrent callers share the same promise. */\nexport function loadPlaidLink(doc: Document = document): Promise<PlaidGlobal> {\n const win = doc.defaultView as WindowWithPlaid | null;\n if (win?.Plaid) return Promise.resolve(win.Plaid);\n if (loader) return loader;\n\n loader = new Promise<PlaidGlobal>((resolve, reject) => {\n const script = doc.createElement('script');\n script.src = PLAID_LINK_SCRIPT_URL;\n script.async = true;\n script.onload = () => {\n const plaid = (doc.defaultView as WindowWithPlaid | null)?.Plaid;\n if (plaid) resolve(plaid);\n else reject(new Error('Plaid Link loaded but did not initialise.'));\n };\n script.onerror = () =>\n reject(new Error('Could not load Plaid Link. Check your connection and try again.'));\n doc.head.appendChild(script);\n }).catch((err: unknown) => {\n // Allow a retry after a failed load (e.g. a transient network error).\n loader = null;\n throw err;\n });\n return loader;\n}\n\nexport type PlaidLinkOutcome =\n | {\n kind: 'success';\n publicToken: string;\n institutionId: string | null;\n institutionName: string | null;\n }\n | { kind: 'exit'; message: string | null };\n\n/**\n * Open Plaid Link for `linkToken` and resolve once the user finishes or\n * leaves. A user closing Link resolves with `kind: 'exit'` (not a rejection);\n * only a failure to load Link itself rejects.\n */\nexport async function openPlaidLink(\n linkToken: string,\n doc: Document = document\n): Promise<PlaidLinkOutcome> {\n const plaid = await loadPlaidLink(doc);\n return new Promise<PlaidLinkOutcome>((resolve) => {\n let settled = false;\n const handler = plaid.create({\n token: linkToken,\n onSuccess: (publicToken, metadata) => {\n if (settled) return;\n settled = true;\n handler.destroy();\n resolve({\n kind: 'success',\n publicToken,\n institutionId: metadata.institution?.institution_id ?? null,\n institutionName: metadata.institution?.name ?? null,\n });\n },\n onExit: (error) => {\n if (settled) return;\n settled = true;\n handler.destroy();\n resolve({ kind: 'exit', message: error?.display_message ?? error?.error_message ?? null });\n },\n });\n handler.open();\n });\n}\n\n/** Test seam: forget a cached loader between tests. */\nexport function resetPlaidLinkLoader(): void {\n loader = null;\n}\n"],"mappings":";AAgBA,IAAa,IAAwB,2DA8BjC,IAAsC;AAG1C,SAAgB,EAAc,IAAgB,UAAgC;CAC5E,IAAM,IAAM,EAAI;CAqBhB,OApBI,GAAK,QAAc,QAAQ,QAAQ,EAAI,KAAK,IAC5C,MAEJ,IAAS,IAAI,SAAsB,GAAS,MAAW;EACrD,IAAM,IAAS,EAAI,cAAc,QAAQ;EAUzC,AATA,EAAO,MAAM,GACb,EAAO,QAAQ,IACf,EAAO,eAAe;GACpB,IAAM,IAAS,EAAI,aAAwC;GAC3D,AAAI,IAAO,EAAQ,CAAK,IACnB,EAAO,gBAAI,MAAM,2CAA2C,CAAC;EACpE,GACA,EAAO,gBACL,EAAO,gBAAI,MAAM,iEAAiE,CAAC,GACrF,EAAI,KAAK,YAAY,CAAM;CAC7B,CAAC,EAAE,OAAO,MAAiB;EAGzB,MADA,IAAS,MACH;CACR,CAAC,GACM;AACT;AAgBA,eAAsB,EACpB,GACA,IAAgB,UACW;CAC3B,IAAM,IAAQ,MAAM,EAAc,CAAG;CACrC,OAAO,IAAI,SAA2B,MAAY;EAChD,IAAI,IAAU,IACR,IAAU,EAAM,OAAO;GAC3B,OAAO;GACP,YAAY,GAAa,MAAa;IAChC,MACJ,IAAU,IACV,EAAQ,QAAQ,GAChB,EAAQ;KACN,MAAM;KACN;KACA,eAAe,EAAS,aAAa,kBAAkB;KACvD,iBAAiB,EAAS,aAAa,QAAQ;IACjD,CAAC;GACH;GACA,SAAS,MAAU;IACb,MACJ,IAAU,IACV,EAAQ,QAAQ,GAChB,EAAQ;KAAE,MAAM;KAAQ,SAAS,GAAO,mBAAmB,GAAO,iBAAiB;IAAK,CAAC;GAC3F;EACF,CAAC;EACD,EAAQ,KAAK;CACf,CAAC;AACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-brainyrich",
3
- "version": "2026.830.2",
3
+ "version": "2026.1025.1",
4
4
  "description": "Burdenoff BrainyRich Microfrontend",
5
5
  "type": "module",
6
6
  "files": [