@alviere/ui 0.15.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -64,6 +64,7 @@ export declare interface FlowConfig {
64
64
  allowBack?: boolean;
65
65
  showProgress?: boolean;
66
66
  showNavigation?: boolean;
67
+ maxReAuths?: number;
67
68
  }
68
69
 
69
70
  export declare interface FlowEvent {
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
10
10
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
11
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
12
  var _a, _commit_callbacks, _discard_callbacks, _pending, _blocking_pending, _deferred, _dirty_effects, _maybe_dirty_effects, _Batch_instances, traverse_effect_tree_fn, defer_effects_fn, clear_marked_fn, resolve_fn, commit_fn, _pending2, _anchor, _hydrate_open, _props, _children, _effect, _main_effect, _pending_effect, _failed_effect, _offscreen_fragment, _pending_anchor, _local_pending_count, _pending_count, _is_creating_fallback, _effect_pending, _effect_pending_subscriber, _Boundary_instances, hydrate_resolved_content_fn, hydrate_pending_content_fn, get_anchor_fn, run_fn, show_pending_snippet_fn, update_pending_count_fn, _batches, _onscreen, _offscreen, _outroing, _transition, _commit, _discard, _events, _instance;
13
- import { AlviereCore, AlcoreApiError, AlcoreErrorCodes, isCriticalError } from "@alviere/core";
13
+ import { AlviereCore, AlcoreApiError, AlcoreErrorCodes, isCriticalError, getJWTRefreshTime } from "@alviere/core";
14
14
  import { onMount, createEventDispatcher, untrack as untrack$1 } from "svelte";
15
15
  const PUBLIC_VERSION = "5";
16
16
  if (typeof window !== "undefined") {
@@ -12705,7 +12705,12 @@ function Callout($$anchor, $$props) {
12705
12705
  }
12706
12706
  customElements.define("alviere-callout", create_custom_element(Callout, { message: {}, variant: {}, role: {}, ariaLive: {} }, [], [], true));
12707
12707
  const createFlowCoreStore = () => {
12708
- const { subscribe, set: set2, update: update2 } = writable({ core: null, isInitialized: false, config: null });
12708
+ const { subscribe, set: set2, update: update2 } = writable({
12709
+ core: null,
12710
+ isInitialized: false,
12711
+ config: null,
12712
+ jwtManager: null
12713
+ });
12709
12714
  return {
12710
12715
  subscribe,
12711
12716
  set: set2,
@@ -12754,11 +12759,22 @@ const createFlowCoreStore = () => {
12754
12759
  return { ...state2, config: { ...state2.config, jwt: newJwt } };
12755
12760
  });
12756
12761
  },
12762
+ /**
12763
+ * Register the JwtManager so child components can call attemptReAuth()
12764
+ */
12765
+ setJwtManager: (manager2) => {
12766
+ update2((state2) => ({ ...state2, jwtManager: manager2 }));
12767
+ },
12757
12768
  /**
12758
12769
  * Reset the store (cleanup)
12759
12770
  */
12760
12771
  reset: () => {
12761
- set2({ core: null, isInitialized: false, config: null });
12772
+ set2({
12773
+ core: null,
12774
+ isInitialized: false,
12775
+ config: null,
12776
+ jwtManager: null
12777
+ });
12762
12778
  },
12763
12779
  /**
12764
12780
  * Get the current core instance (for non-reactive access)
@@ -13449,9 +13465,9 @@ function createAccountStatusGuard(config) {
13449
13465
  notifyBarrier
13450
13466
  };
13451
13467
  }
13452
- const INDIVIDUAL_PAYER = { "profileId": "INDIVIDUAL_PAYER", "config": { "labels": { "finalText": "Payment in process" } }, "steps": [{ "type": "CREATE_CONSUMER_ACCOUNT", "fields": { "first_name": { "required": "First Name is required", "alphabetic": true }, "last_name": { "required": "Last Name is required", "alphabetic": true }, "email_address": { "required": "Email Address is required", "email": true } }, "fieldMeta": { "first_name": { "label": "First Name" }, "last_name": { "label": "Last Name" }, "email_address": { "label": "Email Address" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State/Province" }, "postal_code": { "label": "Postal Code" }, "country": { "label": "Country" } }, "config": { "groups": { "information": "consumer_information" }, "layout": [{ "label": "Personal Information", "group": "consumer_information", "rows": [{ "fields": ["first_name", "last_name"] }, { "fields": ["email_address"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "polling": { "enabled": true, "intervalMs": 2e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {}, "ach_account_type": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" }, "ach_account_type": { "label": "Account Type" } }, "config": { "requireRoutingAndAccountConfirmation": true, "metadata": { "payee_uuid": "{{businessUuid}}" }, "labels": { "prenoteInfoLabel": false, "prenotePendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." } } }, { "type": "CHECKOUT_CONFIRM", "config": { "labels": { "paymentTimingInfoLabel": "Payment is expected to be completed within 3–5 business days.", "paymentTimingPendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." }, "amountEditable": false, "legalTexts": { "required": true, "documents": [{ "type": "ACH_AUTHORIZATION_INDIVIDUAL_PAYER" }] } } }] };
13453
- const BUSINESS_PAYER = { "profileId": "BUSINESS_PAYER", "config": { "labels": { "finalText": "Payment in process" } }, "steps": [{ "type": "CREATE_BUSINESS_ACCOUNT", "fields": { "business_name": { "required": "Business Name is required", "alphabetic": true }, "business_type": { "required": "Business Type is required" }, "country_of_incorporation": { "required": "Country of Incorporation is required" }, "state_of_incorporation": { "required": "State of Incorporation is required" }, "ein": {} }, "fieldMeta": { "business_name": { "label": "Business Name" }, "business_type": { "label": "Business Type" }, "country_of_incorporation": { "label": "Country of Incorporation" }, "state_of_incorporation": { "label": "State of Incorporation" }, "ein": { "label": "EIN" }, "email_address": { "label": "Email Address" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State/Province" }, "postal_code": { "label": "Postal Code" }, "country": { "label": "Country" } }, "config": { "groups": { "information": "business_information" }, "layout": [{ "label": "Business Information", "group": "business_information", "rows": [{ "fields": ["business_name", "business_type"] }, { "fields": ["country_of_incorporation", "state_of_incorporation"] }, { "fields": ["ein"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {}, "ach_account_type": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" }, "ach_account_type": { "label": "Account Type" } }, "config": { "requireRoutingAndAccountConfirmation": true, "metadata": { "payee_uuid": "{{businessUuid}}" }, "labels": { "prenoteInfoLabel": "New bank accounts go through prenote verification. It can take up to 3-5 business days for the account to become ACTIVE and for payments to finish processing.", "prenotePendingInfoLabel": "This bank account is still in prenote verification (PENDING). It can take up to 3-5 business days before it becomes ACTIVE and payments are processed." } } }, { "type": "CHECKOUT_CONFIRM", "config": { "labels": { "paymentTimingInfoLabel": "If this is a newly added bank account, prenote verification can take up to 3-5 business days before the account becomes ACTIVE and the payment is fully processed.", "paymentTimingPendingInfoLabel": "This bank account is still in prenote verification (PENDING). It can take up to 3-5 business days before the account becomes ACTIVE and payment processing completes." }, "amountEditable": false, "legalTexts": { "required": true, "documents": [{ "type": "ACH_AUTHORIZATION_BUSINESS_PAYER" }] } } }] };
13454
- const PAYEE = { "profileId": "PAYEE", "config": { "labels": { "finalText": "Process complete" } }, "steps": [{ "type": "CREATE_BUSINESS_ACCOUNT", "fields": { "business_type": { "required": "Business Type is required" }, "business_name": { "required": "Business Name is required" }, "country_of_incorporation": { "required": "Country of Incorporation is required" }, "state_of_incorporation": { "required": "State of Incorporation is required" }, "nature_of_business": { "required": "Nature of Business is required", "numeric": "Nature of Business must only contain numbers", "minValue": { "value": 11, "message": "Nature of Business must be between 11 and 999999" }, "maxValue": { "value": 999999, "message": "Nature of Business must be between 11 and 999999" } }, "ein": { "required": "EIN is required", "numeric": "EIN must only contain numbers" }, "email_address": { "email": true }, "phone_number": { "required": "Phone Number is required", "phone": true }, "website": { "url": true }, "line_1": { "required": "Address Line 1 is required", "pattern": { "regex": "^.{2,40}$", "message": "Address Line 1 must be between 2 and 40 characters" } }, "line_2": { "pattern": { "regex": "^.{1,30}$", "message": "Address Line 2 must be between 1 and 30 characters" } }, "city": { "required": "City is required" }, "state": { "required": "State is required" }, "postal_code": { "required": "Postal Code is required", "pattern": { "regex": "^.{5,9}$", "message": "Postal Code must be between 5 and 9 characters" } } }, "fieldMeta": { "business_name": { "label": "Business Name" }, "business_type": { "label": "Business Type" }, "country_of_incorporation": { "label": "Country of Incorporation" }, "state_of_incorporation": { "label": "State of Incorporation" }, "nature_of_business": { "label": "Nature of Business (NAICS)" }, "ein": { "label": "EIN" }, "email_address": { "label": "Email Address" }, "phone_number": { "label": "Phone Number" }, "website": { "label": "Website" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State" }, "postal_code": { "label": "Postal Code" } }, "config": { "labels": { "createAccountLabel": "Create Account", "creatingAccountLabel": "Creating Account...", "updateAccountLabel": "Update Account", "updatingAccountLabel": "Updating Account..." }, "groups": { "information": "business_information", "primary_address": "primary_address" }, "layout": [{ "label": "Business Information", "group": "business_information", "rows": [{ "fields": ["business_name", "business_type"] }, { "fields": ["country_of_incorporation", "state_of_incorporation"] }, { "fields": ["nature_of_business", "ein"] }, { "fields": ["email_address", "phone_number"] }, { "fields": ["website"] }] }, { "label": "Address", "group": "primary_address", "rows": [{ "fields": ["line_1"] }, { "fields": ["line_2"] }, { "fields": ["city", "state"] }, { "fields": ["postal_code"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE", "CREATED"], "barrierStatuses": ["MANUAL_REVIEW"], "barrierTitle": "Review in progress", "barrierMessage": "Your account is currently under review. <br />You will be able to continue once the review is complete.", "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "START_ONBOARDING", "config": { "legalTexts": { "required": true, "documents": [{ "type": "TERMS_AND_CONDITIONS" }, { "type": "PRIVACY_POLICY" }] }, "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "barrierStatuses": ["MANUAL_REVIEW"], "barrierTitle": "Manual review in progress", "barrierMessage": "Your account is currently under review. <br />You will be able to continue once the review is complete.", "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" } }, "config": { "labels": { "finalizeButton": "Finalize Onboarding", "prenotePendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." }, "requireRoutingAndAccountConfirmation": true } }] };
13468
+ const INDIVIDUAL_PAYER = { "profileId": "INDIVIDUAL_PAYER", "config": { "maxReAuths": 3, "labels": { "finalText": "Payment in process" } }, "steps": [{ "type": "CREATE_CONSUMER_ACCOUNT", "fields": { "first_name": { "required": "First Name is required", "alphabetic": true }, "last_name": { "required": "Last Name is required", "alphabetic": true }, "email_address": { "required": "Email Address is required", "email": true } }, "fieldMeta": { "first_name": { "label": "First Name" }, "last_name": { "label": "Last Name" }, "email_address": { "label": "Email Address" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State/Province" }, "postal_code": { "label": "Postal Code" }, "country": { "label": "Country" } }, "config": { "groups": { "information": "consumer_information" }, "layout": [{ "label": "Personal Information", "group": "consumer_information", "rows": [{ "fields": ["first_name", "last_name"] }, { "fields": ["email_address"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "polling": { "enabled": true, "intervalMs": 2e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {}, "ach_account_type": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" }, "ach_account_type": { "label": "Account Type" } }, "config": { "requireRoutingAndAccountConfirmation": true, "metadata": { "payee_uuid": "{{businessUuid}}" }, "labels": { "prenoteInfoLabel": false, "prenotePendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." } } }, { "type": "CHECKOUT_CONFIRM", "config": { "labels": { "paymentTimingInfoLabel": "Payment is expected to be completed within 3–5 business days.", "paymentTimingPendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." }, "amountEditable": false, "legalTexts": { "required": true, "documents": [{ "type": "ACH_AUTHORIZATION_INDIVIDUAL_PAYER" }] } } }] };
13469
+ const BUSINESS_PAYER = { "profileId": "BUSINESS_PAYER", "config": { "maxReAuths": 3, "labels": { "finalText": "Payment in process" } }, "steps": [{ "type": "CREATE_BUSINESS_ACCOUNT", "fields": { "business_name": { "required": "Business Name is required", "alphabetic": true }, "business_type": { "required": "Business Type is required" }, "country_of_incorporation": { "required": "Country of Incorporation is required" }, "state_of_incorporation": { "required": "State of Incorporation is required" }, "ein": {} }, "fieldMeta": { "business_name": { "label": "Business Name" }, "business_type": { "label": "Business Type" }, "country_of_incorporation": { "label": "Country of Incorporation" }, "state_of_incorporation": { "label": "State of Incorporation" }, "ein": { "label": "EIN" }, "email_address": { "label": "Email Address" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State/Province" }, "postal_code": { "label": "Postal Code" }, "country": { "label": "Country" } }, "config": { "groups": { "information": "business_information" }, "layout": [{ "label": "Business Information", "group": "business_information", "rows": [{ "fields": ["business_name", "business_type"] }, { "fields": ["country_of_incorporation", "state_of_incorporation"] }, { "fields": ["ein"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {}, "ach_account_type": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" }, "ach_account_type": { "label": "Account Type" } }, "config": { "requireRoutingAndAccountConfirmation": true, "metadata": { "payee_uuid": "{{businessUuid}}" }, "labels": { "prenoteInfoLabel": "New bank accounts go through prenote verification. It can take up to 3-5 business days for the account to become ACTIVE and for payments to finish processing.", "prenotePendingInfoLabel": "This bank account is still in prenote verification (PENDING). It can take up to 3-5 business days before it becomes ACTIVE and payments are processed." } } }, { "type": "CHECKOUT_CONFIRM", "config": { "labels": { "paymentTimingInfoLabel": "If this is a newly added bank account, prenote verification can take up to 3-5 business days before the account becomes ACTIVE and the payment is fully processed.", "paymentTimingPendingInfoLabel": "This bank account is still in prenote verification (PENDING). It can take up to 3-5 business days before the account becomes ACTIVE and payment processing completes." }, "amountEditable": false, "legalTexts": { "required": true, "documents": [{ "type": "ACH_AUTHORIZATION_BUSINESS_PAYER" }] } } }] };
13470
+ const PAYEE = { "profileId": "PAYEE", "config": { "maxReAuths": 3, "labels": { "finalText": "Process complete" } }, "steps": [{ "type": "CREATE_BUSINESS_ACCOUNT", "fields": { "business_type": { "required": "Business Type is required" }, "business_name": { "required": "Business Name is required" }, "country_of_incorporation": { "required": "Country of Incorporation is required" }, "state_of_incorporation": { "required": "State of Incorporation is required" }, "nature_of_business": { "required": "Nature of Business is required", "numeric": "Nature of Business must only contain numbers", "minValue": { "value": 11, "message": "Nature of Business must be between 11 and 999999" }, "maxValue": { "value": 999999, "message": "Nature of Business must be between 11 and 999999" } }, "ein": { "required": "EIN is required", "numeric": "EIN must only contain numbers" }, "email_address": { "email": true }, "phone_number": { "required": "Phone Number is required", "phone": true }, "website": { "url": true }, "line_1": { "required": "Address Line 1 is required", "pattern": { "regex": "^.{2,40}$", "message": "Address Line 1 must be between 2 and 40 characters" } }, "line_2": { "pattern": { "regex": "^.{1,30}$", "message": "Address Line 2 must be between 1 and 30 characters" } }, "city": { "required": "City is required" }, "state": { "required": "State is required" }, "postal_code": { "required": "Postal Code is required", "pattern": { "regex": "^.{5,9}$", "message": "Postal Code must be between 5 and 9 characters" } } }, "fieldMeta": { "business_name": { "label": "Business Name" }, "business_type": { "label": "Business Type" }, "country_of_incorporation": { "label": "Country of Incorporation" }, "state_of_incorporation": { "label": "State of Incorporation" }, "nature_of_business": { "label": "Nature of Business (NAICS)" }, "ein": { "label": "EIN" }, "email_address": { "label": "Email Address" }, "phone_number": { "label": "Phone Number" }, "website": { "label": "Website" }, "line_1": { "label": "Address Line 1" }, "line_2": { "label": "Address Line 2" }, "city": { "label": "City" }, "state": { "label": "State" }, "postal_code": { "label": "Postal Code" } }, "config": { "labels": { "createAccountLabel": "Create Account", "creatingAccountLabel": "Creating Account...", "updateAccountLabel": "Update Account", "updatingAccountLabel": "Updating Account..." }, "groups": { "information": "business_information", "primary_address": "primary_address" }, "layout": [{ "label": "Business Information", "group": "business_information", "rows": [{ "fields": ["business_name", "business_type"] }, { "fields": ["country_of_incorporation", "state_of_incorporation"] }, { "fields": ["nature_of_business", "ein"] }, { "fields": ["email_address", "phone_number"] }, { "fields": ["website"] }] }, { "label": "Address", "group": "primary_address", "rows": [{ "fields": ["line_1"] }, { "fields": ["line_2"] }, { "fields": ["city", "state"] }, { "fields": ["postal_code"] }] }], "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE", "CREATED"], "barrierStatuses": ["MANUAL_REVIEW"], "barrierTitle": "Review in progress", "barrierMessage": "Your account is currently under review. <br />You will be able to continue once the review is complete.", "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "START_ONBOARDING", "config": { "legalTexts": { "required": true, "documents": [{ "type": "TERMS_AND_CONDITIONS" }, { "type": "PRIVACY_POLICY" }] }, "statusPolicy": { "allowedStatusesForNextStep": ["ACTIVE"], "barrierStatuses": ["MANUAL_REVIEW"], "barrierTitle": "Manual review in progress", "barrierMessage": "Your account is currently under review. <br />You will be able to continue once the review is complete.", "polling": { "enabled": true, "intervalMs": 3e3, "maxRetries": 5, "terminalStatuses": ["FAILED", "REJECTED"], "onTerminal": "error" } } } }, { "type": "ADD_BANK_ACCOUNT", "fields": { "ach_routing_number": {}, "ach_account_number": {} }, "fieldMeta": { "ach_routing_number": { "label": "Routing Number", "helpText": "You can find your routing number on your check or bank statement." }, "ach_account_number": { "label": "Account Number" } }, "config": { "labels": { "finalizeButton": "Finalize Onboarding", "prenotePendingInfoLabel": "Bank account validation and payment is expected to be completed within 5–7 business days." }, "requireRoutingAndAccountConfirmation": true } }] };
13455
13471
  const recipesJson = {
13456
13472
  INDIVIDUAL_PAYER,
13457
13473
  BUSINESS_PAYER,
@@ -16068,6 +16084,34 @@ customElements.define("alviere-create-consumer-account", create_custom_element(
16068
16084
  [],
16069
16085
  true
16070
16086
  ));
16087
+ function getErrorCode(error) {
16088
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
16089
+ if (!error || typeof error !== "object") return void 0;
16090
+ const parsed = error;
16091
+ const parsedMessageCode = typeof parsed.message === "string" ? (_a2 = parsed.message.match(/Alcore API Error\s+(\d+)/)) == null ? void 0 : _a2[1] : void 0;
16092
+ return parsed.errorCode || parsed.error_code || parsed.code || ((_b = parsed.cause) == null ? void 0 : _b.errorCode) || ((_c = parsed.cause) == null ? void 0 : _c.error_code) || ((_d = parsed.cause) == null ? void 0 : _d.code) || ((_f = (_e = parsed.response) == null ? void 0 : _e.data) == null ? void 0 : _f.errorCode) || ((_h = (_g = parsed.response) == null ? void 0 : _g.data) == null ? void 0 : _h.error_code) || parsedMessageCode || void 0;
16093
+ }
16094
+ async function classifyApiError(error, jwtManager) {
16095
+ const errorCode = getErrorCode(error);
16096
+ if (errorCode === AlcoreErrorCodes.INVALID_JWT) {
16097
+ if (jwtManager == null ? void 0 : jwtManager.canReAuth()) {
16098
+ const success = await jwtManager.attemptReAuth();
16099
+ if (success) return { kind: "reauth-success" };
16100
+ }
16101
+ return { kind: "critical", error, errorCode };
16102
+ }
16103
+ if (errorCode && isCriticalError(errorCode)) {
16104
+ return { kind: "critical", error, errorCode };
16105
+ }
16106
+ return { kind: "non-critical", errorCode };
16107
+ }
16108
+ function toAlcoreApiError(error, errorCode) {
16109
+ if (error instanceof AlcoreApiError) return error;
16110
+ return new AlcoreApiError(
16111
+ errorCode || "000000",
16112
+ error instanceof Error ? error.message : "An unexpected error occurred"
16113
+ );
16114
+ }
16071
16115
  const bankInfoCache = /* @__PURE__ */ new Map();
16072
16116
  async function lookupRoutingNumber(routingNumber, alviereCore) {
16073
16117
  const cleanRouting = routingNumber.replace(/[-\s]/g, "");
@@ -16157,6 +16201,7 @@ function AddBankAccount($$anchor, $$props) {
16157
16201
  push($$props, true);
16158
16202
  append_styles$1($$anchor, $$css$b);
16159
16203
  const $flowRecipeStore = () => store_get(flowRecipeStore, "$flowRecipeStore", $$stores);
16204
+ const $flowCoreStore = () => store_get(flowCoreStore, "$flowCoreStore", $$stores);
16160
16205
  const [$$stores, $$cleanup] = setup_stores();
16161
16206
  var _a2;
16162
16207
  var _b;
@@ -16424,10 +16469,17 @@ function AddBankAccount($$anchor, $$props) {
16424
16469
  if (baseForm.state.validationErrors.ach_routing_number === invalidRoutingNumberMessage) {
16425
16470
  baseForm.actions.clearFieldError("ach_routing_number");
16426
16471
  }
16427
- }).catch((error) => {
16472
+ }).catch(async (error) => {
16428
16473
  set(bankInfo, null);
16429
- baseForm.actions.setFieldError("ach_routing_number", invalidRoutingNumberMessage);
16430
- uiLogger.warn("Failed to lookup bank info:", error);
16474
+ const result = await classifyApiError(error, $flowCoreStore().jwtManager);
16475
+ if (result.kind === "reauth-success") {
16476
+ baseForm.actions.clearFieldError("ach_routing_number");
16477
+ } else if (result.kind === "critical") {
16478
+ dispatchCriticalError(result.error, result.errorCode);
16479
+ } else {
16480
+ baseForm.actions.setFieldError("ach_routing_number", invalidRoutingNumberMessage);
16481
+ uiLogger.warn("Failed to lookup bank info:", error);
16482
+ }
16431
16483
  }).finally(() => {
16432
16484
  set(isLoadingBankInfo, false);
16433
16485
  });
@@ -16517,12 +16569,14 @@ function AddBankAccount($$anchor, $$props) {
16517
16569
  set(isSubmitting, false);
16518
16570
  }
16519
16571
  }
16520
- function getErrorCode(error) {
16521
- var _a3, _b2, _c2, _d, _e, _f, _g, _h;
16522
- if (!error || typeof error !== "object") return void 0;
16523
- const parsed = error;
16524
- const parsedMessageCode = typeof parsed.message === "string" ? (_a3 = parsed.message.match(/Alcore API Error\s+(\d+)/)) === null || _a3 === void 0 ? void 0 : _a3[1] : void 0;
16525
- return parsed.errorCode || parsed.error_code || parsed.code || ((_b2 = parsed.cause) === null || _b2 === void 0 ? void 0 : _b2.errorCode) || ((_c2 = parsed.cause) === null || _c2 === void 0 ? void 0 : _c2.error_code) || ((_d = parsed.cause) === null || _d === void 0 ? void 0 : _d.code) || ((_f = (_e = parsed.response) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.errorCode) || ((_h = (_g = parsed.response) === null || _g === void 0 ? void 0 : _g.data) === null || _h === void 0 ? void 0 : _h.error_code) || parsedMessageCode || void 0;
16572
+ function dispatchCriticalError(error, errorCode) {
16573
+ if (get$1(hostElement)) {
16574
+ get$1(hostElement).dispatchEvent(new CustomEvent(ComponentEvents.FORM_ERROR, {
16575
+ detail: { error: toAlcoreApiError(error, errorCode), stepType },
16576
+ bubbles: true,
16577
+ composed: true
16578
+ }));
16579
+ }
16526
16580
  }
16527
16581
  function getAddBankAccountErrorMessage(errorCode) {
16528
16582
  if (errorCode === "340029") {
@@ -16545,8 +16599,15 @@ function AddBankAccount($$anchor, $$props) {
16545
16599
  async function handleAddBankAccount(event2) {
16546
16600
  var _a3, _b2;
16547
16601
  event2.preventDefault();
16602
+ if (get$1(isLoadingBankInfo)) {
16603
+ return;
16604
+ }
16548
16605
  baseForm.actions.markAllFieldsAsInteracted();
16549
16606
  baseForm.actions.validateAllFields();
16607
+ const routingOnSubmit = baseForm.state.formData.ach_details.routing_number;
16608
+ if (baseForm.state.alviereCore && (routingOnSubmit === null || routingOnSubmit === void 0 ? void 0 : routingOnSubmit.length) === 9 && !get$1(isLoadingBankInfo) && get$1(bankInfo) === null) {
16609
+ baseForm.actions.setFieldError("ach_routing_number", getFieldErrorMessage("ach_routing_number", "pattern", INVALID_ROUTING_NUMBER_MESSAGE));
16610
+ }
16550
16611
  if (!baseForm.computed.canSubmit) {
16551
16612
  uiLogger.debug("Cannot submit: form validation failed");
16552
16613
  return;
@@ -16626,8 +16687,14 @@ function AddBankAccount($$anchor, $$props) {
16626
16687
  set(showAddForm, false);
16627
16688
  } catch (error) {
16628
16689
  uiLogger.error("❌ Error adding bank account:", error);
16629
- const errorCode = getErrorCode(error);
16630
- set(formError, getAddBankAccountErrorMessage(errorCode), true);
16690
+ const result = await classifyApiError(error, $flowCoreStore().jwtManager);
16691
+ if (result.kind === "reauth-success") {
16692
+ set(formError, "Your session has been refreshed. Please try again.");
16693
+ } else if (result.kind === "critical") {
16694
+ dispatchCriticalError(result.error, result.errorCode);
16695
+ } else {
16696
+ set(formError, getAddBankAccountErrorMessage(result.errorCode), true);
16697
+ }
16631
16698
  } finally {
16632
16699
  set(isSubmitting, false);
16633
16700
  }
@@ -17233,6 +17300,7 @@ function AddBankAccount($$anchor, $$props) {
17233
17300
  baseForm.state.formData.ach_details.type = newValue;
17234
17301
  baseForm.handlers.handleFieldChange("ach_account_type", newValue);
17235
17302
  },
17303
+ onblur: () => baseForm.handlers.handleFieldBlur("ach_account_type"),
17236
17304
  get validationSchema() {
17237
17305
  return get$1(fieldSchemas).ach_account_type;
17238
17306
  },
@@ -17307,6 +17375,13 @@ function AddBankAccount($$anchor, $$props) {
17307
17375
  if (get$1(requireRoutingAndAccountConfirmation) && baseForm.state.formData.confirm_routing_number) {
17308
17376
  validateRoutingConfirmation();
17309
17377
  }
17378
+ },
17379
+ onblur: () => {
17380
+ baseForm.handlers.handleFieldBlur("ach_routing_number");
17381
+ const routing = baseForm.state.formData.ach_details.routing_number;
17382
+ if (baseForm.state.alviereCore && (routing == null ? void 0 : routing.length) === 9 && !get$1(isLoadingBankInfo) && get$1(bankInfo) === null) {
17383
+ baseForm.actions.setFieldError("ach_routing_number", getFieldErrorMessage("ach_routing_number", "pattern", INVALID_ROUTING_NUMBER_MESSAGE));
17384
+ }
17310
17385
  }
17311
17386
  });
17312
17387
  }
@@ -17352,6 +17427,10 @@ function AddBankAccount($$anchor, $$props) {
17352
17427
  validateRoutingConfirmation();
17353
17428
  }
17354
17429
  },
17430
+ onblur: () => {
17431
+ baseForm.handlers.handleFieldBlur("confirm_routing_number");
17432
+ validateRoutingConfirmation();
17433
+ },
17355
17434
  blockPaste: true
17356
17435
  });
17357
17436
  }
@@ -17420,7 +17499,8 @@ function AddBankAccount($$anchor, $$props) {
17420
17499
  if (get$1(requireRoutingAndAccountConfirmation) && baseForm.state.formData.confirm_account_number) {
17421
17500
  validateAccountConfirmation();
17422
17501
  }
17423
- }
17502
+ },
17503
+ onblur: () => baseForm.handlers.handleFieldBlur("ach_account_number")
17424
17504
  });
17425
17505
  }
17426
17506
  var node_23 = sibling(node_22, 2);
@@ -17466,6 +17546,10 @@ function AddBankAccount($$anchor, $$props) {
17466
17546
  validateAccountConfirmation();
17467
17547
  }
17468
17548
  },
17549
+ onblur: () => {
17550
+ baseForm.handlers.handleFieldBlur("confirm_account_number");
17551
+ validateAccountConfirmation();
17552
+ },
17469
17553
  blockPaste: true
17470
17554
  });
17471
17555
  }
@@ -19606,13 +19690,20 @@ delegate(["click"]);
19606
19690
  create_custom_element(FormErrorBoundary, { onError: {}, allowRetry: {}, children: {} }, [], ["handleError", "reset"], true);
19607
19691
  function createJwtFlowManager(options) {
19608
19692
  const { getJwt, getCore, getDebug, onJwtUpdate } = options;
19693
+ const getMaxReAuths = () => {
19694
+ var _a2;
19695
+ return ((_a2 = options.getMaxReAuths) == null ? void 0 : _a2.call(options)) ?? 3;
19696
+ };
19609
19697
  let effectiveJwt = /* @__PURE__ */ state(proxy(getJwt()));
19610
19698
  let pendingJwt = /* @__PURE__ */ state(null);
19611
19699
  let stepJwtSnapshot = /* @__PURE__ */ state(proxy(getJwt()));
19700
+ let reAuthCount = 0;
19701
+ let refreshTimer = null;
19612
19702
  user_effect(() => {
19613
19703
  const currentJwt = getJwt();
19614
19704
  if (currentJwt) {
19615
19705
  set(effectiveJwt, currentJwt, true);
19706
+ scheduleRefresh(currentJwt);
19616
19707
  }
19617
19708
  });
19618
19709
  user_effect(() => {
@@ -19623,7 +19714,7 @@ function createJwtFlowManager(options) {
19623
19714
  set(pendingJwt, null);
19624
19715
  const debug = getDebug();
19625
19716
  if (debug) {
19626
- uiLogger.info("✅ JWT downgrade successful - updated flow JWT");
19717
+ uiLogger.info("✅ JWT update successful - updated flow JWT");
19627
19718
  uiLogger.info("🔐 Old JWT (first 50 chars):", oldJwt == null ? void 0 : oldJwt.substring(0, 50));
19628
19719
  uiLogger.info("🔐 New JWT (first 50 chars):", (_a2 = get$1(effectiveJwt)) == null ? void 0 : _a2.substring(0, 50));
19629
19720
  uiLogger.info("🔐 New JWT will be used in all subsequent steps");
@@ -19631,11 +19722,72 @@ function createJwtFlowManager(options) {
19631
19722
  onJwtUpdate == null ? void 0 : onJwtUpdate(get$1(effectiveJwt));
19632
19723
  }
19633
19724
  });
19725
+ function scheduleRefresh(jwt) {
19726
+ if (refreshTimer !== null) {
19727
+ clearTimeout(refreshTimer);
19728
+ refreshTimer = null;
19729
+ }
19730
+ const refreshAtMs = getJWTRefreshTime(jwt);
19731
+ if (!refreshAtMs) return;
19732
+ const delay = refreshAtMs - Date.now();
19733
+ if (delay <= 0) {
19734
+ getDebug() && uiLogger.warn("⏰ JWT refresh time already passed — triggering immediately");
19735
+ attemptReAuth().then((success) => {
19736
+ var _a2;
19737
+ if (!success) (_a2 = options.onReAuthExhausted) == null ? void 0 : _a2.call(options);
19738
+ });
19739
+ return;
19740
+ }
19741
+ getDebug() && uiLogger.info(`⏰ JWT refresh scheduled in ${Math.round(delay / 1e3)}s (at ${new Date(refreshAtMs).toISOString()})`);
19742
+ refreshTimer = setTimeout(
19743
+ async () => {
19744
+ var _a2;
19745
+ refreshTimer = null;
19746
+ getDebug() && uiLogger.info("⏰ JWT refresh timer fired — attempting re-auth");
19747
+ const success = await attemptReAuth();
19748
+ if (!success) {
19749
+ (_a2 = options.onReAuthExhausted) == null ? void 0 : _a2.call(options);
19750
+ }
19751
+ },
19752
+ delay
19753
+ );
19754
+ }
19755
+ async function attemptReAuth() {
19756
+ const maxReAuths = getMaxReAuths();
19757
+ if (reAuthCount >= maxReAuths) {
19758
+ getDebug() && uiLogger.warn(`🔐 Re-auth limit reached (${reAuthCount}/${maxReAuths}) — cannot re-authenticate`);
19759
+ return false;
19760
+ }
19761
+ const core = getCore();
19762
+ if (!core) {
19763
+ getDebug() && uiLogger.warn("⚠️ Cannot re-auth — AlviereCore not initialized");
19764
+ return false;
19765
+ }
19766
+ try {
19767
+ const accountUuid = core.getAccountUuid();
19768
+ if (!accountUuid) {
19769
+ getDebug() && uiLogger.warn("⚠️ Cannot re-auth — account UUID not available in JWT");
19770
+ return false;
19771
+ }
19772
+ getDebug() && uiLogger.info(`🔐 Attempting re-auth (${reAuthCount + 1}/${maxReAuths}) for account: ${accountUuid}`);
19773
+ const newJwt = await core.generateScopedToken(accountUuid, false);
19774
+ reAuthCount++;
19775
+ getDebug() && uiLogger.info(`✅ Re-auth successful (${reAuthCount}/${maxReAuths})`);
19776
+ set(pendingJwt, newJwt, true);
19777
+ await new Promise((resolve) => setTimeout(resolve, 0));
19778
+ scheduleRefresh(newJwt);
19779
+ return true;
19780
+ } catch (error) {
19781
+ uiLogger.warn("⚠️ Re-auth attempt failed:", error);
19782
+ return false;
19783
+ }
19784
+ }
19634
19785
  return {
19635
19786
  getJwtForStep: () => get$1(stepJwtSnapshot),
19636
19787
  getEffectiveJwt: () => get$1(effectiveJwt),
19637
19788
  updateJwt: (newJwt) => {
19638
19789
  set(effectiveJwt, newJwt, true);
19790
+ scheduleRefresh(newJwt);
19639
19791
  },
19640
19792
  downgradeJwt: async (accountUuid) => {
19641
19793
  const core = getCore();
@@ -19659,12 +19811,22 @@ function createJwtFlowManager(options) {
19659
19811
  set(pendingJwt, newJwt, true);
19660
19812
  debug && uiLogger.info("🔐 Pending JWT set (first 50 chars):", newJwt == null ? void 0 : newJwt.substring(0, 50));
19661
19813
  await new Promise((resolve) => setTimeout(resolve, 0));
19814
+ scheduleRefresh(newJwt);
19662
19815
  } catch (error) {
19663
19816
  uiLogger.warn("⚠️ Failed to perform JWT downgrade:", error);
19664
19817
  }
19665
19818
  },
19666
19819
  updateStepSnapshot: () => {
19667
19820
  set(stepJwtSnapshot, untrack$1(() => get$1(effectiveJwt)), true);
19821
+ },
19822
+ canReAuth: () => reAuthCount < getMaxReAuths(),
19823
+ attemptReAuth,
19824
+ cancelRefreshTimer: () => {
19825
+ if (refreshTimer !== null) {
19826
+ clearTimeout(refreshTimer);
19827
+ refreshTimer = null;
19828
+ getDebug() && uiLogger.info("⏰ JWT refresh timer cancelled");
19829
+ }
19668
19830
  }
19669
19831
  };
19670
19832
  }
@@ -20147,8 +20309,27 @@ function MultiStepFlow($$anchor, $$props) {
20147
20309
  onJwtUpdate: (newJwt) => {
20148
20310
  flowCoreStore.updateJwt(newJwt);
20149
20311
  jwt(newJwt);
20312
+ },
20313
+ // maxReAuths is read reactively from the resolved recipe config (or FlowConfig prop)
20314
+ getMaxReAuths: () => {
20315
+ var _a3, _b2, _c;
20316
+ return (_c = (_a3 = config() === null || config() === void 0 ? void 0 : config().maxReAuths) !== null && _a3 !== void 0 ? _a3 : (_b2 = get$1(profileRecipe) === null || get$1(profileRecipe) === void 0 ? void 0 : get$1(profileRecipe).config) === null || _b2 === void 0 ? void 0 : _b2.maxReAuths) !== null && _c !== void 0 ? _c : 3;
20317
+ },
20318
+ onReAuthExhausted: () => {
20319
+ debug() && uiLogger.warn("🔐 Re-auth exhausted — halting flow with critical error");
20320
+ set(flowBarrier, null);
20321
+ set(
20322
+ flowError,
20323
+ {
20324
+ message: get$1(criticalErrorMessage),
20325
+ errorCode: "100305",
20326
+ description: "Authentication session expired and could not be renewed."
20327
+ },
20328
+ true
20329
+ );
20150
20330
  }
20151
20331
  });
20332
+ flowCoreStore.setJwtManager(jwtManager);
20152
20333
  const flowManager = createFlowStateManager(() => config());
20153
20334
  const eventDispatcher = createFlowEventDispatcher({
20154
20335
  getFlowElement: () => get$1(
@@ -20357,6 +20538,7 @@ function MultiStepFlow($$anchor, $$props) {
20357
20538
  }
20358
20539
  return () => {
20359
20540
  debug() && uiLogger.info("🧹 Cleaning up flow - resetting AlviereCore store");
20541
+ jwtManager.cancelRefreshTimer();
20360
20542
  resetFlowCore();
20361
20543
  resetFlowRecipe();
20362
20544
  };