@movmo_app/payments 0.2.1 → 0.3.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
@@ -37,6 +37,95 @@ export declare interface CardholderTokenizeData {
37
37
  zip?: string;
38
38
  }
39
39
 
40
+ /**
41
+ * Builds an auth-aware `fetch` that the payments package (or any other
42
+ * consumer that registers it via `setPaymentsConfig({ fetch })`) can call.
43
+ * See file header for the full contract.
44
+ */
45
+ export declare const createMovmoAuthFetch: (options: CreateMovmoAuthFetchOptions) => typeof fetch;
46
+
47
+ /**
48
+ * Auth-aware `fetch` wrapper for `@movmo_app/payments`. The package's API
49
+ * helpers call through `getPaymentsConfig().fetch`, bypassing whatever axios
50
+ * interceptor stack the consumer wires up. Without this wrapper:
51
+ *
52
+ * - Session cookie expiry → silent 401/403 (no refresh, no logout).
53
+ * - State-mutating endpoints → 403 because the CSRF cookie isn't echoed.
54
+ * - Local-dev / multi-tenant flows → missing per-request headers like
55
+ * `X-Movmo-Proxy-Auth` or `movmo-customer-id`.
56
+ *
57
+ * This factory replaces a ~95-line `paymentsFetch.ts` copy that was
58
+ * duplicated across consumer apps. The contract:
59
+ *
60
+ * 1. CSRF token from `csrfCookieName` is set on every request as
61
+ * `X-CSRF-Token` (matching the axios interceptor's unconditional set).
62
+ * 2. `extraHeaders(input, init)` is invoked per-request to allow dynamic
63
+ * headers (proxy-auth, customer id, etc.). Headers the caller already
64
+ * set on `init.headers` win — `extraHeaders` only fills gaps.
65
+ * 3. `credentials: 'include'` is forced so the session cookie travels.
66
+ * 4. On a 401/403 from a non-auth endpoint, the wrapper calls
67
+ * `refreshSession()` once (concurrent failures share one in-flight
68
+ * promise) and retries the original request. If refresh ITSELF fails,
69
+ * `onRefreshFailed(err)` fires so the consumer can drive a sign-out —
70
+ * silently swallowing here would strand the user on a broken page.
71
+ * Failures on the *retry* fetch are logged and the original response is
72
+ * returned so the SDK still sees a Response to render an error from.
73
+ * 5. The original fetch's network errors (offline, CORS, DNS) propagate.
74
+ * Only retry-path failures are caught; pre-refresh errors are left for
75
+ * the consumer to surface.
76
+ *
77
+ * The duplicated copies that this replaces both silently swallowed refresh
78
+ * failure (see review issue #1 on both PR #47 + PR #180). Making
79
+ * `onRefreshFailed` *required* enforces at the type level that consumers
80
+ * wire up a logout path.
81
+ */
82
+ export declare interface CreateMovmoAuthFetchOptions {
83
+ /**
84
+ * Refreshes the session cookie. Called once on the first 401/403; concurrent
85
+ * 401/403s share the same in-flight promise. Resolved value is ignored — the
86
+ * wrapper only cares about success vs. rejection. Must rotate the session
87
+ * cookie (and CSRF cookie, if applicable) such that a retry with the same
88
+ * request will succeed.
89
+ */
90
+ refreshSession: () => Promise<unknown>;
91
+ /**
92
+ * Fired when `refreshSession()` itself rejects. The consumer MUST treat this
93
+ * as a terminal auth failure and trigger a sign-out + redirect — otherwise
94
+ * the user is stranded on a broken page with `authState.isAuthenticated`
95
+ * still true.
96
+ *
97
+ * Receives the underlying rejection so the consumer can log it.
98
+ */
99
+ onRefreshFailed: (error: unknown) => void;
100
+ /**
101
+ * Cookie name carrying the CSRF token. Defaults to `movmo_csrf_token`.
102
+ */
103
+ csrfCookieName?: string;
104
+ /**
105
+ * Optional per-request header builder. Evaluated on every call (not cached)
106
+ * so dynamically-changing headers (e.g. `movmo-customer-id` driven by a
107
+ * route param) reflect the current value. Headers the caller already set
108
+ * on `init.headers` always win — `extraHeaders` only fills gaps.
109
+ */
110
+ extraHeaders?: (input: RequestInfo | URL, init?: RequestInit) => Record<string, string>;
111
+ /**
112
+ * Substring used to detect requests that must NOT trigger the refresh
113
+ * retry — typically the auth-refresh endpoint itself, to avoid an
114
+ * infinite recursion when refresh returns 401. Defaults to `/v1/auth/`.
115
+ */
116
+ authPathFragment?: string;
117
+ /**
118
+ * Underlying fetch impl. Defaults to `globalThis.fetch.bind(globalThis)`.
119
+ * Override only for tests or non-browser environments.
120
+ */
121
+ baseFetch?: typeof fetch;
122
+ /**
123
+ * Cookie reader. Defaults to reading `document.cookie`. Override only in
124
+ * non-browser test environments — the default works in jsdom.
125
+ */
126
+ readCookie?: (name: string) => string | null;
127
+ }
128
+
40
129
  export declare const getPaymentsConfig: () => InternalPaymentsConfig;
41
130
 
42
131
  /* Excluded from this release type: InternalPaymentsConfig */