tempest-react-sdk 0.83.0 → 0.85.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.
Files changed (70) hide show
  1. package/README.md +1 -0
  2. package/dist/auth/create-tempest-auth.cjs +1 -1
  3. package/dist/auth/create-tempest-auth.cjs.map +1 -1
  4. package/dist/auth/create-tempest-auth.js +294 -178
  5. package/dist/auth/create-tempest-auth.js.map +1 -1
  6. package/dist/components/Markdown/Markdown.cjs +1 -1
  7. package/dist/components/Markdown/Markdown.cjs.map +1 -1
  8. package/dist/components/Markdown/Markdown.js +29 -28
  9. package/dist/components/Markdown/Markdown.js.map +1 -1
  10. package/dist/components/Markdown/markdown-parse.cjs +6 -5
  11. package/dist/components/Markdown/markdown-parse.cjs.map +1 -1
  12. package/dist/components/Markdown/markdown-parse.js +195 -160
  13. package/dist/components/Markdown/markdown-parse.js.map +1 -1
  14. package/dist/http/resumable-upload.cjs +1 -1
  15. package/dist/http/resumable-upload.cjs.map +1 -1
  16. package/dist/http/resumable-upload.js +1 -1
  17. package/dist/http/resumable-upload.js.map +1 -1
  18. package/dist/http/upload-with-progress.cjs +1 -1
  19. package/dist/http/upload-with-progress.cjs.map +1 -1
  20. package/dist/http/upload-with-progress.js +47 -39
  21. package/dist/http/upload-with-progress.js.map +1 -1
  22. package/dist/payments/PixCheckout.cjs +2 -0
  23. package/dist/payments/PixCheckout.cjs.map +1 -0
  24. package/dist/payments/PixCheckout.js +171 -0
  25. package/dist/payments/PixCheckout.js.map +1 -0
  26. package/dist/payments/PixCheckout.module.cjs +3 -0
  27. package/dist/payments/PixCheckout.module.cjs.map +1 -0
  28. package/dist/payments/PixCheckout.module.js +22 -0
  29. package/dist/payments/PixCheckout.module.js.map +1 -0
  30. package/dist/payments/format.cjs +2 -0
  31. package/dist/payments/format.cjs.map +1 -0
  32. package/dist/payments/format.js +9 -0
  33. package/dist/payments/format.js.map +1 -0
  34. package/dist/payments/mercado-pago.cjs +2 -0
  35. package/dist/payments/mercado-pago.cjs.map +1 -0
  36. package/dist/payments/mercado-pago.js +27 -0
  37. package/dist/payments/mercado-pago.js.map +1 -0
  38. package/dist/payments/outcome.cjs +2 -0
  39. package/dist/payments/outcome.cjs.map +1 -0
  40. package/dist/payments/outcome.js +111 -0
  41. package/dist/payments/outcome.js.map +1 -0
  42. package/dist/payments/types.cjs +2 -0
  43. package/dist/payments/types.cjs.map +1 -0
  44. package/dist/payments/types.js +16 -0
  45. package/dist/payments/types.js.map +1 -0
  46. package/dist/payments/use-mercado-pago-card.cjs +2 -0
  47. package/dist/payments/use-mercado-pago-card.cjs.map +1 -0
  48. package/dist/payments/use-mercado-pago-card.js +128 -0
  49. package/dist/payments/use-mercado-pago-card.js.map +1 -0
  50. package/dist/payments/use-pix-charge.cjs +2 -0
  51. package/dist/payments/use-pix-charge.cjs.map +1 -0
  52. package/dist/payments/use-pix-charge.js +71 -0
  53. package/dist/payments/use-pix-charge.js.map +1 -0
  54. package/dist/query/offline-persistence.cjs +1 -1
  55. package/dist/query/offline-persistence.cjs.map +1 -1
  56. package/dist/query/offline-persistence.js +100 -54
  57. package/dist/query/offline-persistence.js.map +1 -1
  58. package/dist/styles/PixCheckout.css +2 -0
  59. package/dist/styles/component/PixCheckout.css +18 -0
  60. package/dist/styles/manifest.json +6 -0
  61. package/dist/styles/payments.css +18 -0
  62. package/dist/styles.css +1 -1
  63. package/dist/sw/cache.cjs +1 -1
  64. package/dist/sw/cache.cjs.map +1 -1
  65. package/dist/sw/cache.js +1 -1
  66. package/dist/sw/cache.js.map +1 -1
  67. package/dist/tempest-react-sdk.cjs +1 -1
  68. package/dist/tempest-react-sdk.d.ts +913 -29
  69. package/dist/tempest-react-sdk.js +104 -97
  70. package/package.json +1 -1
@@ -3138,8 +3138,96 @@ export declare function capitalize(value: string): string;
3138
3138
  */
3139
3139
  export declare function Card({ title, actions, footer, flush, interactive, elevation, className, children, ...props }: CardProps): JSX.Element;
3140
3140
 
3141
+ /**
3142
+ * PT-BR text for every `status_detail` Mercado Pago's Orders API documents.
3143
+ *
3144
+ * Ported from Mercado Pago's "Status da transação" table
3145
+ * (`developers/pt/docs/checkout-api-orders/payment-management/status/transaction-status`,
3146
+ * read on 2026-11-14), rewritten for the payer: the provider's descriptions are
3147
+ * addressed to the integrator. `rejected_by_issuer` is the decline the backend
3148
+ * pinned in the sandbox (holder `OTHE`, HTTP 402); the others come from the
3149
+ * table. `high_risk` deliberately does not say "fraud" — telling the payer the
3150
+ * anti-fraud system flagged them helps exactly the person it should not.
3151
+ *
3152
+ * A test pins every key, so a code dropped or renamed here fails instead of
3153
+ * silently falling back to the generic text.
3154
+ */
3155
+ export declare const CARD_STATUS_DETAIL_MESSAGES: Readonly<Record<string, string>>;
3156
+
3157
+ /** A card charge — `CardCharge` in the backend. */
3158
+ export declare interface CardCharge {
3159
+ /** Provider that owns the charge. */
3160
+ provider: string;
3161
+ /** The charge's id at the provider. */
3162
+ provider_charge_id: string;
3163
+ /** The service's own identifier. */
3164
+ reference: string;
3165
+ /** Amount charged, in cents. */
3166
+ amount_cents: number;
3167
+ /** How much went back to the payer, in cents. A partial refund keeps `status` at `paid`. */
3168
+ refunded_cents: number;
3169
+ /** ISO 4217 code. */
3170
+ currency: string;
3171
+ /**
3172
+ * Canonical state. A declined card is `"failed"` — returned, not raised: the
3173
+ * backend answers the decline as a charge, with the reason in `status_detail`.
3174
+ */
3175
+ status: PaymentStatus;
3176
+ /** The provider's raw state. */
3177
+ provider_status: string;
3178
+ /** The provider's reason — `rejected_by_issuer`, `waiting_capture`, `accredited`. */
3179
+ status_detail: string | null;
3180
+ /** Card brand. */
3181
+ payment_method_id: string | null;
3182
+ /** Installments charged. */
3183
+ installments: number | null;
3184
+ /** Each installment, interest included, in cents. */
3185
+ installment_amount_cents: number | null;
3186
+ /** What the payer owes with interest, in cents. Not proof of payment — read `status`. */
3187
+ payer_total_cents: number | null;
3188
+ /** The provider's payload as decoded. */
3189
+ raw?: Record<string, unknown>;
3190
+ }
3191
+
3192
+ /**
3193
+ * The body a service needs to charge a tokenized card — `CardChargeRequest` in
3194
+ * the backend, minus nothing: `card_token`, `payment_method_id` and
3195
+ * `installments` are exactly what {@link useMercadoPagoCard}'s `tokenize`
3196
+ * returns, and the card number is never part of it.
3197
+ */
3198
+ export declare interface CardChargeRequest {
3199
+ /** The price in cents. With installments, still the price: the provider adds the interest. */
3200
+ amount_cents: number;
3201
+ /** The service's own identifier — also the create's idempotency key. */
3202
+ reference: string;
3203
+ /** Single-use token produced in the browser. */
3204
+ card_token: string;
3205
+ /** Card brand as the provider names it (`visa`, `master`, …). */
3206
+ payment_method_id: string;
3207
+ /** Installments the payer chose. Default `1` on the backend. */
3208
+ installments?: number;
3209
+ /** `false` only authorizes; the charge comes back `authorized`. Default `true`. */
3210
+ capture?: boolean;
3211
+ /** Free text, where the provider supports it. */
3212
+ description?: string | null;
3213
+ /** Who is paying. */
3214
+ payer?: PaymentPayer | null;
3215
+ }
3216
+
3141
3217
  export declare type CardElevation = "flat" | "default" | "raised" | "elevated";
3142
3218
 
3219
+ /** One installment choice, in the shape a `<Select>` needs. */
3220
+ export declare interface CardInstallmentOption {
3221
+ /** Number of installments — the value to submit. */
3222
+ installments: number;
3223
+ /** The provider's own text, e.g. `"2 parcelas de R$ 54,82 (R$ 109,64)"`. Show it verbatim. */
3224
+ recommendedMessage: string;
3225
+ /** Each installment, interest included, in cents. */
3226
+ installmentAmountCents: number;
3227
+ /** What the payer owes in total, interest included, in cents. */
3228
+ totalAmountCents: number;
3229
+ }
3230
+
3143
3231
  export declare interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
3144
3232
  title?: ReactNode;
3145
3233
  actions?: ReactNode;
@@ -3151,6 +3239,34 @@ export declare interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>,
3151
3239
  elevation?: CardElevation;
3152
3240
  }
3153
3241
 
3242
+ /** What the non-card part of the form supplies when tokenizing. */
3243
+ export declare interface CardTokenizeInput {
3244
+ /** Name printed on the card. */
3245
+ cardholderName: string;
3246
+ /** Installments chosen from {@link UseMercadoPagoCardResult.installmentOptions}. */
3247
+ installments: number;
3248
+ /** Document type (`"CPF"`, `"CNPJ"`). */
3249
+ identificationType?: string;
3250
+ /** Document number, digits only. */
3251
+ identificationNumber?: string;
3252
+ }
3253
+
3254
+ /**
3255
+ * Everything the backend needs to charge the card — and nothing more.
3256
+ *
3257
+ * Maps onto the backend's `CardChargeRequest` as `card_token: token` plus the
3258
+ * other two fields unchanged. No card number, expiry or CVV: those never left
3259
+ * Mercado Pago's iframes.
3260
+ */
3261
+ export declare interface CardTokenResult {
3262
+ /** Single-use card token. */
3263
+ token: string;
3264
+ /** Card brand as Mercado Pago names it (`visa`, `master`, …). */
3265
+ payment_method_id: string;
3266
+ /** Installments chosen. */
3267
+ installments: number;
3268
+ }
3269
+
3154
3270
  /**
3155
3271
  * Horizontal content slider showing one slide at a time.
3156
3272
  *
@@ -4933,6 +5049,10 @@ export declare function createLinkStatsSampler(options?: LinkStatsSamplerOptions
4933
5049
  * `clear()` forgets every record under the prefix. Call it from
4934
5050
  * `onSessionEnd`: a record outlives the session that wrote it, and only
4935
5051
  * completing the upload or `abort({ discard: true })` removes it otherwise.
5052
+ * It also ends every handle built over a storage with the same prefix: a run
5053
+ * in flight stops with {@link ResumableUploadSupersededError} (`"cleared"`),
5054
+ * and a paused one's next `resume()` starts a new upload with a fresh
5055
+ * `Idempotency-Key` (since 0.84.0, #528).
4936
5056
  *
4937
5057
  * @param prefix - Key prefix. Default `"tempest-upload:"`.
4938
5058
  * @returns A storage that no-ops when `localStorage` is unavailable.
@@ -5605,8 +5725,10 @@ export declare interface CreateStorePersistOptions<T> {
5605
5725
  * mints and every rotation keeps — not by comparing users, which took two
5606
5726
  * sign-ins whose user had not loaded yet for the same account (#544). Two tabs
5607
5727
  * never redeem the same refresh token at once: the redemption runs under an
5608
- * origin-wide Web Lock when the browser has one. `storage: "session"` is per
5609
- * tab and behaves as before.
5728
+ * origin-wide Web Lock when the browser has one, and a redemption installed as
5729
+ * a sign-in — `restore()`, an account switch — holds a second one until it is
5730
+ * installed, so no tab presents the token it spent meanwhile (#594).
5731
+ * `storage: "session"` is per tab and behaves as before.
5610
5732
  *
5611
5733
  * Refreshes are collapsed per rotation, not just per overlap: a `401` whose
5612
5734
  * request left with a token that has since been replaced in the same session
@@ -7255,6 +7377,38 @@ export declare interface DescribeApiErrorOptions extends Partial<ApiErrorStrings
7255
7377
  */
7256
7378
  export declare function describeAppError(error: unknown, context?: Record<string, unknown>): AppErrorDescription;
7257
7379
 
7380
+ /**
7381
+ * Turn a card charge from the backend into what the payer should read.
7382
+ *
7383
+ * The **status** decides the outcome; `status_detail` only refines the sentence.
7384
+ * That ordering is the point: `waiting_capture` arrives as `authorized` and
7385
+ * reads as "reserved, not charged", never as paid, and a detail this table does
7386
+ * not know falls back to the status's generic text instead of guessing — and
7387
+ * "know" means an own key of the table, so a status or detail named after an
7388
+ * `Object.prototype` member (`toString`, `constructor`, `__proto__`) reads as
7389
+ * `unknown` / unknown detail instead of a half-empty outcome. A
7390
+ * decline reason only refines a `failed` charge, and a pending reason only a
7391
+ * charge that is not `failed`, so a detail that contradicts its status cannot
7392
+ * put "recusado" and "reservado" on the same screen.
7393
+ *
7394
+ * A decline is data here, not an exception. The backend returns a declined card
7395
+ * as a `CardCharge` with `status: "failed"` — Mercado Pago answers it with HTTP
7396
+ * 402 and the backend reads that as a result — so the checkout renders the
7397
+ * reason the same way it renders an approval. If your own endpoint chooses to
7398
+ * answer a decline with a non-2xx status, parse its body and pass it here; do
7399
+ * not show it as a network error, because it is not one.
7400
+ *
7401
+ * @param charge - The charge, or just its `status` and `status_detail`.
7402
+ * @param messages - Overrides per `status_detail`, merged over
7403
+ * {@link CARD_STATUS_DETAIL_MESSAGES} — for another language or tone.
7404
+ * @returns Tone, title, message and whether the payer can retry.
7405
+ *
7406
+ * @example
7407
+ * const outcome = describeCardCharge(charge);
7408
+ * <Alert variant={outcome.tone} title={outcome.title} description={outcome.message} />
7409
+ */
7410
+ export declare function describeCardCharge(charge: Pick<CardCharge, "status" | "status_detail">, messages?: Readonly<Record<string, string>>): PaymentOutcome;
7411
+
7258
7412
  /**
7259
7413
  * One filter, in words: `"Status é Pago"`.
7260
7414
  *
@@ -8666,6 +8820,21 @@ export declare interface FormatPhoneOptions {
8666
8820
  mobile?: boolean;
8667
8821
  }
8668
8822
 
8823
+ /**
8824
+ * `mm:ss` under an hour, `h:mm:ss` above — a Pix can live for 24 h.
8825
+ *
8826
+ * The default countdown format of `PixCheckout`, exported so an app that
8827
+ * renders its own Pix screen shows the same clock.
8828
+ *
8829
+ * @param ms - Milliseconds left. Rounded up, so the last second reads `00:01`.
8830
+ * @returns The formatted remaining time.
8831
+ *
8832
+ * @example
8833
+ * formatPixRemaining(65_000); // "01:05"
8834
+ * formatPixRemaining(3_725_000); // "1:02:05"
8835
+ */
8836
+ export declare function formatPixRemaining(ms: number): string;
8837
+
8669
8838
  export declare function FormField<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>>({ name, label, helperText, required, control, children }: FormFieldProps<TValues, TName>): JSX.Element;
8670
8839
 
8671
8840
  export declare interface FormFieldChildProps {
@@ -9944,6 +10113,23 @@ export declare function isDefined<T>(value: T | null | undefined): value is T;
9944
10113
  */
9945
10114
  export declare function isEmpty(value: unknown): boolean;
9946
10115
 
10116
+ /**
10117
+ * Whether a checkout has nothing left to wait for.
10118
+ *
10119
+ * `paid`, `expired`, `cancelled`, `refunded`, `charged_back` and `failed` end the
10120
+ * flow the payer is looking at, so a status poll stops there. `pending`,
10121
+ * `authorized`, `in_analysis` and `unknown` do not: each is a state the backend
10122
+ * will still move. `paid` can later become `refunded`, but that is no longer
10123
+ * something the checkout screen waits for.
10124
+ *
10125
+ * @param status - The charge's canonical state.
10126
+ * @returns `true` when following the charge further is pointless.
10127
+ *
10128
+ * @example
10129
+ * if (isFinalPaymentStatus(charge.status)) stopPolling();
10130
+ */
10131
+ export declare function isFinalPaymentStatus(status: PaymentStatus): boolean;
10132
+
9947
10133
  /**
9948
10134
  * Whether this environment can present anything fullscreen at all.
9949
10135
  *
@@ -10807,6 +10993,44 @@ export { LoaderFunction }
10807
10993
 
10808
10994
  export { LoaderFunctionArgs }
10809
10995
 
10996
+ /**
10997
+ * Load MercadoPago.js once per document and resolve its constructor.
10998
+ *
10999
+ * Concurrent and repeated calls share one `<script>` tag and one promise, so a
11000
+ * checkout that remounts never injects the script twice. A failed load is
11001
+ * forgotten instead of cached — the next call tries again, which is what a
11002
+ * payer on a flaky connection needs — and the dead tag is removed.
11003
+ *
11004
+ * Trust: an existing `window.MercadoPago` is used as is, and `src` is not
11005
+ * checked. Neither is a boundary the page can enforce — whoever can define that
11006
+ * global already runs script here, and an unversioned script has no integrity
11007
+ * hash to pin — so the control is the page's CSP `script-src`, restricted to
11008
+ * `https://sdk.mercadopago.com` or the proxy `src` points at.
11009
+ *
11010
+ * @param options - Script URL and target document.
11011
+ * @returns The `MercadoPago` constructor.
11012
+ * @throws {Error} When the script fails to load, or loads without defining
11013
+ * `window.MercadoPago`.
11014
+ *
11015
+ * @example
11016
+ * const MercadoPago = await loadMercadoPago();
11017
+ * const mp = new MercadoPago(import.meta.env.VITE_MP_PUBLIC_KEY, { locale: "pt-BR" });
11018
+ */
11019
+ export declare function loadMercadoPago(options?: LoadMercadoPagoOptions): Promise<MercadoPagoConstructor>;
11020
+
11021
+ /** Options for {@link loadMercadoPago}. */
11022
+ export declare interface LoadMercadoPagoOptions {
11023
+ /**
11024
+ * Script URL. Default {@link MERCADO_PAGO_SCRIPT_URL}; override only for a
11025
+ * proxy you control that serves the **identical** MercadoPago.js — SAQ A
11026
+ * depends on the fields coming from the processor unaltered. Not checked:
11027
+ * the script is unversioned, so there is no stable integrity hash to pin.
11028
+ */
11029
+ src?: string;
11030
+ /** Document to inject into. Default the global `document`. */
11031
+ document?: Document;
11032
+ }
11033
+
10810
11034
  export declare type LocalStorageOptions<T> = {
10811
11035
  serialize?: (value: T) => string;
10812
11036
  deserialize?: (raw: string) => T;
@@ -11306,6 +11530,123 @@ export declare interface MenubarProps extends HTMLAttributes<HTMLDivElement> {
11306
11530
  portal?: boolean;
11307
11531
  }
11308
11532
 
11533
+ /**
11534
+ * The official MercadoPago.js v2 script.
11535
+ *
11536
+ * Loaded from Mercado Pago's own host, never bundled or vendored: the PCI DSS
11537
+ * self-assessment that keeps a merchant in the lightest scope (SAQ A) requires
11538
+ * the card fields to come straight from the processor, and Mercado Pago ships
11539
+ * the script unversioned so fixes reach every merchant without a rebuild. It is
11540
+ * also why this is not an npm dependency — there is no package to pin.
11541
+ *
11542
+ * A Content-Security-Policy needs `script-src https://sdk.mercadopago.com` and,
11543
+ * for the Secure Fields iframes and the API calls the script makes,
11544
+ * `frame-src https://secure-fields.mercadopago.com https://api-static.mercadopago.com`
11545
+ * plus `connect-src https://api.mercadopago.com https://api.mercadolibre.com`
11546
+ * (hosts read from the script itself, `js_version` 2.83.6, on 2026-11-14).
11547
+ */
11548
+ export declare const MERCADO_PAGO_SCRIPT_URL = "https://sdk.mercadopago.com/js/v2";
11549
+
11550
+ /** Element ids the three Secure Fields mount into. */
11551
+ export declare interface MercadoPagoCardContainers {
11552
+ cardNumber: string;
11553
+ expirationDate: string;
11554
+ securityCode: string;
11555
+ }
11556
+
11557
+ /** Lifecycle of the Secure Fields. */
11558
+ export declare type MercadoPagoCardStatus = "loading" | "ready" | "error";
11559
+
11560
+ /**
11561
+ * What `fields.createCardToken` resolves with — the subset this module reads.
11562
+ *
11563
+ * The Secure Fields iframe posts the card to `POST /v1/card_tokens` and answers
11564
+ * with that endpoint's JSON as is (read from the iframe served by
11565
+ * `secure-fields.mercadopago.com` on 2026-11-14), so the shape is the card token
11566
+ * resource: `CardTokenResponse` in Mercado Pago's own Node SDK (`mercadopago`
11567
+ * 3.6.2), where every field is optional. `first_six_digits` is the BIN of the
11568
+ * card that was actually tokenized, which is how {@link useMercadoPagoCard}
11569
+ * binds the token to the brand it quoted.
11570
+ */
11571
+ export declare interface MercadoPagoCardToken {
11572
+ /** Single-use token id. */
11573
+ id: string;
11574
+ /** First six digits of the tokenized card. */
11575
+ first_six_digits?: string;
11576
+ }
11577
+
11578
+ /** Non-card data the token is bound to. */
11579
+ export declare interface MercadoPagoCardTokenData {
11580
+ cardholderName: string;
11581
+ identificationType?: string;
11582
+ identificationNumber?: string;
11583
+ }
11584
+
11585
+ /** The `MercadoPago` global the script defines. */
11586
+ export declare type MercadoPagoConstructor = new (publicKey: string, options?: {
11587
+ locale?: string;
11588
+ }) => MercadoPagoLike;
11589
+
11590
+ /** One mounted Secure Field — the subset of MercadoPago.js this module calls. */
11591
+ export declare interface MercadoPagoFieldLike {
11592
+ /** Mounts the iframe into the element with this id. */
11593
+ mount(containerId: string): unknown;
11594
+ /** Removes the iframe. */
11595
+ unmount(): unknown;
11596
+ /** Subscribes to a field event (`binChange`, `validityChange`, `error`, …). */
11597
+ on(event: string, listener: (payload: unknown) => void): unknown;
11598
+ }
11599
+
11600
+ /** Options for one Secure Field, as MercadoPago.js accepts them. */
11601
+ export declare interface MercadoPagoFieldOptions {
11602
+ /** Placeholder shown inside the iframe. */
11603
+ placeholder?: string;
11604
+ /** Inline style applied inside the iframe (font, colour, size). */
11605
+ style?: Record<string, string>;
11606
+ }
11607
+
11608
+ /** The Secure Fields this module mounts. */
11609
+ export declare type MercadoPagoFieldType = "cardNumber" | "expirationDate" | "securityCode";
11610
+
11611
+ /** One entry of the `getInstallments` answer. */
11612
+ export declare interface MercadoPagoInstallmentsEntry {
11613
+ payment_method_id: string;
11614
+ payment_type_id?: string;
11615
+ issuer?: {
11616
+ id?: string | number | null;
11617
+ } | null;
11618
+ payer_costs: MercadoPagoPayerCost[];
11619
+ }
11620
+
11621
+ /**
11622
+ * The subset of a `new MercadoPago(publicKey)` instance this module calls.
11623
+ *
11624
+ * Declared here instead of depending on `@mercadopago/sdk-js`, matching how the
11625
+ * SDK treats every injected provider: tests pass a fake with this shape, and an
11626
+ * app never pays for typings it does not use.
11627
+ */
11628
+ export declare interface MercadoPagoLike {
11629
+ fields: {
11630
+ create(type: MercadoPagoFieldType, options?: MercadoPagoFieldOptions): MercadoPagoFieldLike;
11631
+ createCardToken(data: MercadoPagoCardTokenData): Promise<MercadoPagoCardToken>;
11632
+ };
11633
+ getInstallments(params: {
11634
+ amount: string;
11635
+ bin: string;
11636
+ paymentTypeId?: string;
11637
+ }): Promise<MercadoPagoInstallmentsEntry[]>;
11638
+ }
11639
+
11640
+ /** One installment option, as `getInstallments` returns it. */
11641
+ export declare interface MercadoPagoPayerCost {
11642
+ installments: number;
11643
+ installment_rate: number;
11644
+ installment_amount: number;
11645
+ total_amount: number;
11646
+ /** Ready-made text, e.g. `"2 parcelas de R$ 54,82 (R$ 109,64)"`. */
11647
+ recommended_message: string;
11648
+ }
11649
+
11309
11650
  /**
11310
11651
  * A point projected onto the unit Web Mercator plane. Both axes are in `[0, 1]`
11311
11652
  * — `x` grows east, `y` grows south (screen convention).
@@ -12152,6 +12493,15 @@ export declare interface OfflineQueryClearOptions {
12152
12493
  * Default `false`: the client belongs to the app, which may want to keep
12153
12494
  * public queries (a catalog, feature flags) across sessions and drop only
12154
12495
  * the user-scoped keys with `removeQueries`.
12496
+ *
12497
+ * With `auth`, only the reset lets a new handle on the same client persist
12498
+ * the next session. Without it the client still holds the ended session's
12499
+ * responses, so `clear()` marks the client's session record ended and
12500
+ * every handle on it deletes its row instead of writing, until the client
12501
+ * is reset or a handle is created on it with empty caches. Before 0.85.0,
12502
+ * `clear()` dropped that record, and the handle created at login stamped
12503
+ * the previous account's responses with the new one (security audit
12504
+ * run-13, C1).
12155
12505
  */
12156
12506
  resetClient?: boolean;
12157
12507
  }
@@ -12162,15 +12512,23 @@ export declare interface OfflineQueryPersistence {
12162
12512
  * Load the persisted snapshot into the `QueryClient`. Call once on boot,
12163
12513
  * before rendering queries, so cached data is available offline. A no-op
12164
12514
  * once {@link OfflineQueryPersistence.clear} has been called, and — with
12165
- * `getPrincipal` — for a snapshot written under another principal.
12515
+ * `getPrincipal` — for a snapshot written under another principal or while
12516
+ * `isPrincipalKnown` returns `false`; call it again once it is known.
12166
12517
  */
12167
12518
  restore: () => Promise<void>;
12168
12519
  /**
12169
12520
  * Write the current cache snapshot immediately (bypassing the throttle). A
12170
- * no-op once {@link OfflineQueryPersistence.clear} has been called.
12521
+ * no-op once {@link OfflineQueryPersistence.clear} has been called, and,
12522
+ * with `auth`, once {@link OfflineQueryPersistence.unsubscribe} has.
12171
12523
  */
12172
12524
  flush: () => Promise<void>;
12173
- /** Stop persisting and drop the pending write. Idempotent. */
12525
+ /**
12526
+ * Stop persisting and drop the pending write. Idempotent.
12527
+ *
12528
+ * With `auth`, a later `flush()` writes nothing: the handle no longer sees
12529
+ * sessions installed and ended, so it cannot tell whose responses the
12530
+ * cache holds (security audit run-13, N3).
12531
+ */
12174
12532
  unsubscribe: () => void;
12175
12533
  /**
12176
12534
  * End the persisted session (e.g. on logout) and delete the snapshot.
@@ -12201,6 +12559,15 @@ export declare interface OfflineQueryPersistence {
12201
12559
  * user-scoped keys with `removeQueries`. Because persistence is already
12202
12560
  * off, that manual call can come before or after this one.
12203
12561
  *
12562
+ * With `auth`, the reset decides whether the next session persists on the
12563
+ * same client. With it, the client's session record is dropped after
12564
+ * `queryClient.clear()`, and a handle created at login persists the new
12565
+ * account. Without it, the client still holds this session's responses,
12566
+ * so the record is marked ended — never dropped — and every handle on the
12567
+ * client, a new one or one on another `key`, deletes its row instead of
12568
+ * writing until the client is reset or a handle is created on it with
12569
+ * empty caches (security audit run-13, C1).
12570
+ *
12204
12571
  * Idempotent and safe to call concurrently; every call deletes the row
12205
12572
  * again.
12206
12573
  *
@@ -12225,9 +12592,9 @@ export declare interface OfflineQueryPersistenceOptions {
12225
12592
  /**
12226
12593
  * Who is signed in right now — a stable, non-secret id such as the user id;
12227
12594
  * `null`/`undefined` when nobody is. Read on every write, which stamps the
12228
- * snapshot with a one-way fingerprint of it (never the id itself), and on
12595
+ * snapshot with a one-way fingerprint of it (never the id itself), on
12229
12596
  * `restore()`, which hydrates only a snapshot stamped with the same
12230
- * fingerprint.
12597
+ * fingerprint, and on cache changes until the handle is bound.
12231
12598
  *
12232
12599
  * `clear()` on logout already deletes the snapshot; this covers the session
12233
12600
  * that ends without it — a token that expired, a crash, a tab closed while
@@ -12240,11 +12607,14 @@ export declare interface OfflineQueryPersistenceOptions {
12240
12607
  * the principal after a `/me` round trip would otherwise wipe its own cache
12241
12608
  * on every cold start. The next write replaces it.
12242
12609
  *
12243
- * The handle is bound to the first signed-in owner it writes or restores.
12244
- * Once bound, a write under another owner — nobody, because the token
12245
- * expired without `clear()`, or a second account on the same tab — deletes
12246
- * the snapshot instead of stamping the bound owner's cached responses with
12247
- * the new owner (#563); the same owner coming back writes again. Writes
12610
+ * The handle is bound to the first signed-in owner it sees on a cache
12611
+ * change, a write or a restore — the cache change is what pins the owner of
12612
+ * data that a throttled write would otherwise stamp with whoever is signed
12613
+ * in a second later (#580). Once bound, a write under another owner —
12614
+ * nobody, because the token expired without `clear()`, or a second account
12615
+ * on the same tab — deletes the snapshot instead of stamping the bound
12616
+ * owner's cached responses with the new owner (#563); the same owner coming
12617
+ * back writes again. Writes
12248
12618
  * before anyone signs in stay anonymous and are restored while nobody is,
12249
12619
  * so an app that persists logged-out data keeps doing so. An anonymous
12250
12620
  * snapshot written by 0.82.0 is not restored (it may hold an expired
@@ -12253,8 +12623,121 @@ export declare interface OfflineQueryPersistenceOptions {
12253
12623
  * Read synchronously. A non-string, non-number value (the `Promise` of an
12254
12624
  * `async` getter) or a getter that throws reads as nobody. Omit it to restore
12255
12625
  * every snapshot, as before 0.82.0.
12626
+ *
12627
+ * `null` and `undefined` both mean **nobody is signed in** — the same
12628
+ * contract as every other `getPrincipal` in the SDK, so `() => user?.id`
12629
+ * keeps working. "Not known yet" (a cookie session before `/me` answers) is
12630
+ * a different state, and this getter cannot express it: pass
12631
+ * {@link OfflineQueryPersistenceOptions.isPrincipalKnown} for it. Without
12632
+ * that, a write that runs before `/me` stamps the signed-in user's
12633
+ * responses as anonymous, and a logged-out boot hydrates them (#590).
12634
+ *
12635
+ * A handle that hydrated an anonymous snapshot deletes it, instead of
12636
+ * writing, once someone signs in on it: the anonymous row may hold a
12637
+ * previous account's responses written before its principal was known, and
12638
+ * stamping them with the account now signed in is what handed them to it
12639
+ * (#590). To keep persisting, end it with `clear({ resetClient: true })`
12640
+ * and create a new handle: the in-memory client still holds what the
12641
+ * deleted row held, and a new handle on it would stamp that with the
12642
+ * account signed in. With {@link OfflineQueryPersistenceOptions.auth} a new
12643
+ * handle on such a client keeps deleting until the client is reset; with
12644
+ * `getPrincipal` alone, resetting it is up to the app.
12256
12645
  */
12257
12646
  getPrincipal?: () => string | number | null | undefined;
12647
+ /**
12648
+ * Whether `getPrincipal` already reflects the real session. Only read with
12649
+ * `getPrincipal`; omitted, the principal is always known, as before.
12650
+ *
12651
+ * For an app that learns who is signed in only after a round trip — a
12652
+ * cookie session resolved by `/me`, a token restored asynchronously —
12653
+ * return `false` until that answer arrives, whatever it is. While it is
12654
+ * `false`:
12655
+ *
12656
+ * - a write does not run and is re-armed for the next throttle window, so
12657
+ * the responses already in the cache are stamped with the real owner, not
12658
+ * as anonymous;
12659
+ * - a cache change does not bind the handle;
12660
+ * - `restore()` hydrates nothing — call it again once the principal is
12661
+ * known.
12662
+ *
12663
+ * Without it, `null` before `/me` reads as "nobody": a session that ends
12664
+ * (tab closed) inside the first throttle window leaves the signed-in user's
12665
+ * responses stamped anonymous, for the next logged-out boot to hydrate
12666
+ * (#590).
12667
+ *
12668
+ * Read synchronously; a throw reads as not known, so it fails closed.
12669
+ *
12670
+ * With {@link OfflineQueryPersistenceOptions.auth} there is no need for
12671
+ * it; when both are given, both must say known.
12672
+ */
12673
+ isPrincipalKnown?: () => boolean;
12674
+ /**
12675
+ * The auth preset whose session owns the cache — pass what
12676
+ * `createTempestAuth` returned. The safe wiring for an app built on it:
12677
+ *
12678
+ * - the principal is `auth.sessionKey()` unless
12679
+ * {@link OfflineQueryPersistenceOptions.getPrincipal} is given, so the
12680
+ * cache belongs to one sign-in and survives reloads and token rotations
12681
+ * of it; a new sign-in of the same account starts cold;
12682
+ * - the principal is known only while `auth.isSessionKnown()` says the
12683
+ * session is settled — not while a `login()`, `restore()` or the boot
12684
+ * `refresh()` is still deciding it — and, with a `getPrincipal` of your
12685
+ * own, only once it names someone whenever a session is installed (a
12686
+ * user id read from a profile that has not loaded yet is not "nobody");
12687
+ * - every session installed while the `QueryClient`'s cache lives is
12688
+ * recorded — the preset notifies each install, and every cache change,
12689
+ * write and restore reads `sessionKey()` too — not only the one a cache
12690
+ * change happens to see. Once a second session, or nobody after one,
12691
+ * was installed — a sign-out in another tab, a `logout()` without
12692
+ * `clear()`, a second `login()` on top —, every write deletes the row
12693
+ * and `restore()` hydrates nothing: the cache may hold the ended
12694
+ * session's responses, including one the api client replayed with the
12695
+ * bearer of a `login()` or boot `refresh()` that started after the
12696
+ * request left with no token and ended before it landed (security audit
12697
+ * run-12, C1). Nobody followed by a session is not an end, and a
12698
+ * token rotation keeps the key;
12699
+ * - that record belongs to the `QueryClient`, not to the handle, so a new
12700
+ * handle on the same client keeps deleting. Only a reset drops it:
12701
+ * `clear({ resetClient: true })`, after which nothing of the ended
12702
+ * session stays in memory, or creating a handle on a client with empty
12703
+ * caches. `clear()` without `resetClient` leaves the client as it is,
12704
+ * so it marks the record ended instead: no handle on that client
12705
+ * persists until it is reset (security audit run-13, C1);
12706
+ * - a handle only records sessions while it observes them: after
12707
+ * `unsubscribe()` its `flush()` writes nothing, and a handle created on
12708
+ * a client that already holds responses cannot know which session
12709
+ * fetched them — create it before the first query, at boot;
12710
+ * A session that is not this preset (an object of your own) is only
12711
+ * read on cache changes, writes and restores, so a session installed
12712
+ * and ended between two of them goes unseen;
12713
+ * - a `sessionKey()` that throws reads as not known, so nothing is written.
12714
+ *
12715
+ * It does not call `clear()` on session end by itself: `clear()` ends the
12716
+ * handle, and the row is already deleted on the next write. Keep calling
12717
+ * `clear()` on logout, which also stops persisting at once.
12718
+ *
12719
+ * Before it, a cookie app had to wire `isPrincipalKnown` by hand, and the
12720
+ * doc saying so was the only guard: without it, a tab closed before `/me`
12721
+ * answered left the signed-in account's responses stamped anonymous for
12722
+ * the next signed-out boot to hydrate (#596). Call `restore()` after the
12723
+ * boot `auth.refresh()` settles; called before, it hydrates only what
12724
+ * nobody owns.
12725
+ */
12726
+ auth?: OfflineQuerySession;
12727
+ }
12728
+
12729
+ /**
12730
+ * The session a {@link persistQueryClientOffline} handle follows — what
12731
+ * `createTempestAuth` returns satisfies it, so pass the preset as is.
12732
+ *
12733
+ * Structural on purpose: the query module does not import the auth preset,
12734
+ * so an app that persists its cache without it pays nothing for it.
12735
+ */
12736
+ export declare interface OfflineQuerySession {
12737
+ /** The key of the session signed in now, or `null` when nobody is. */
12738
+ sessionKey: () => string | null;
12739
+ /** Whether that session is settled, see `TempestAuth.isSessionKnown`. */
12740
+ isSessionKnown: () => boolean;
12258
12741
  }
12259
12742
 
12260
12743
  /** Maps each table name to the record type it stores. */
@@ -13213,6 +13696,57 @@ export { PathMatch }
13213
13696
 
13214
13697
  export { PathPattern }
13215
13698
 
13699
+ /** What a card charge means to the payer, ready to render. */
13700
+ export declare interface PaymentOutcome {
13701
+ /** The canonical state the outcome was derived from. */
13702
+ status: PaymentStatus;
13703
+ /** Tone for the surrounding `Alert`/`Badge`. */
13704
+ tone: PaymentOutcomeTone;
13705
+ /** Short headline. */
13706
+ title: string;
13707
+ /** One sentence telling the payer what happened and what to do. */
13708
+ message: string;
13709
+ /** Whether the payer can fix it from the checkout (another card, other data). */
13710
+ canRetry: boolean;
13711
+ }
13712
+
13713
+ /** Visual tone of an outcome, matching `Alert`'s variants. */
13714
+ export declare type PaymentOutcomeTone = "success" | "info" | "warning" | "danger" | "neutral";
13715
+
13716
+ /** Who is paying — `PixPayer` in the backend, shared by Pix and card requests. */
13717
+ export declare interface PaymentPayer {
13718
+ /** Full name. */
13719
+ name?: string | null;
13720
+ /** CPF or CNPJ, digits or formatted. */
13721
+ tax_id?: string | null;
13722
+ /** E-mail. Mercado Pago requires it on a card charge (`payer.email`). */
13723
+ email?: string | null;
13724
+ /** Phone number. */
13725
+ phone?: string | null;
13726
+ }
13727
+
13728
+ /**
13729
+ * The payment contract as the `tempest-fastapi-sdk` backend serialises it.
13730
+ *
13731
+ * Every shape here is the JSON a service built on that SDK answers with — the
13732
+ * Pydantic schemas in `tempest_fastapi_sdk/integrations/payment/base.py`, dumped
13733
+ * with `model_dump(mode="json")`. The field names stay in snake_case because
13734
+ * `BaseSchema` declares no alias generator, so that is what crosses the wire;
13735
+ * renaming them here would make every app write a mapper that can drift.
13736
+ *
13737
+ * Datetimes arrive as ISO 8601 strings and money as integer cents, never as a
13738
+ * float: the backend refuses floats for money on purpose, and so does this side.
13739
+ */
13740
+ /**
13741
+ * The canonical state of a charge — `PaymentStatusEnum` in the backend.
13742
+ *
13743
+ * `"unknown"` is a real state, not a fallback: the backend uses it for a
13744
+ * provider state its version does not classify, keeping the provider's own
13745
+ * string in `provider_status`. A screen should show it as "we are checking",
13746
+ * never as paid or failed.
13747
+ */
13748
+ export declare type PaymentStatus = "pending" | "authorized" | "paid" | "expired" | "cancelled" | "refunded" | "charged_back" | "in_analysis" | "failed" | "unknown";
13749
+
13216
13750
  /** Raw PCM ready to be wrapped in a RIFF container. */
13217
13751
  export declare interface PcmAudio {
13218
13752
  /** One `Float32Array` per channel, samples in −1…1. */
@@ -13512,6 +14046,105 @@ export declare type PinInputSize = "sm" | "md" | "lg";
13512
14046
 
13513
14047
  export declare type PinInputType = "numeric" | "alphanumeric";
13514
14048
 
14049
+ /** A Pix charge — `PixCharge` in the backend. */
14050
+ export declare interface PixCharge {
14051
+ /** Provider that owns the charge (`"mercado_pago"`, `"openpix"`, …). */
14052
+ provider: string;
14053
+ /** The charge's id at the provider. */
14054
+ provider_charge_id: string;
14055
+ /** The service's own identifier for the charge. */
14056
+ reference: string;
14057
+ /** Amount in cents. */
14058
+ amount_cents: number;
14059
+ /** ISO 4217 code; `"BRL"` for Pix. */
14060
+ currency: string;
14061
+ /** Canonical state — the only field a screen branches on. */
14062
+ status: PaymentStatus;
14063
+ /** The provider's raw state, for support and logs. */
14064
+ provider_status: string;
14065
+ /** EMV copia-e-cola string. */
14066
+ br_code: string | null;
14067
+ /** QR as a Base64 PNG, without the `data:` prefix (Mercado Pago fills it). */
14068
+ qr_code_base64: string | null;
14069
+ /** QR as a URL (OpenPix fills it instead of the Base64). */
14070
+ qr_code_image_url: string | null;
14071
+ /** Pix end-to-end id, once the provider reports one. */
14072
+ end_to_end_id: string | null;
14073
+ /** When the charge stops being payable, ISO 8601. */
14074
+ expires_at: string | null;
14075
+ /** When it settled, ISO 8601. */
14076
+ paid_at: string | null;
14077
+ /** The provider's payload as decoded. A screen should not read it. */
14078
+ raw?: Record<string, unknown>;
14079
+ }
14080
+
14081
+ /**
14082
+ * The payer's Pix screen: amount, QR, copia-e-cola, countdown and the state the
14083
+ * backend reports.
14084
+ *
14085
+ * Presentational and controlled. It renders `charge` and never changes it, so
14086
+ * the decision that a Pix was paid stays where it can be made — on the backend,
14087
+ * re-reading the order. Feed it from {@link usePixCharge} or from your own
14088
+ * stream.
14089
+ *
14090
+ * The QR comes from `qr_code_base64` when the provider sent one (Mercado Pago),
14091
+ * and is otherwise drawn locally from `br_code` (OpenPix sends a URL instead,
14092
+ * and fetching it would hand the payload to an image host for nothing). The
14093
+ * copia-e-cola line is always next to it: a QR cannot be scanned by the phone
14094
+ * that is showing it, which is where a mobile checkout puts it.
14095
+ *
14096
+ * A status this version does not know renders as `unknown` ("verificando"). Known
14097
+ * means an own key of the state table, so a status named after an
14098
+ * `Object.prototype` member (`toString`, `constructor`) is unknown too, instead
14099
+ * of an empty state block.
14100
+ *
14101
+ * When the countdown reaches zero while the backend still says `pending`, the
14102
+ * screen hides the QR and says it is **confirming** — not "expired". A payment
14103
+ * sent in the last second can still settle, and only the backend knows.
14104
+ *
14105
+ * @example
14106
+ * const { charge } = usePixCharge(created, { refresh: (signal) => readCharge(created.provider_charge_id, signal) });
14107
+ * <PixCheckout charge={charge} />
14108
+ */
14109
+ export declare function PixCheckout({ charge, qrSize, labels, formatRemaining, onCopied, footer, className, ...rest }: PixCheckoutProps): JSX.Element;
14110
+
14111
+ /** Strings the screen renders, so an app can translate them. */
14112
+ export declare interface PixCheckoutLabels {
14113
+ /** Accessible name of the QR. */
14114
+ qr: string;
14115
+ /** Heading over the copia-e-cola line. */
14116
+ copyHint: string;
14117
+ /** Copy button, idle. */
14118
+ copy: string;
14119
+ /** Copy button, just clicked. */
14120
+ copied: string;
14121
+ /** Prefix of the countdown, e.g. "Expira em". */
14122
+ expiresIn: string;
14123
+ /** Shown when the deadline passed but the backend has not said "expired" yet. */
14124
+ confirming: string;
14125
+ /** Title and description per terminal or waiting state. */
14126
+ states: Record<PaymentStatus, {
14127
+ title: string;
14128
+ description: string;
14129
+ }>;
14130
+ }
14131
+
14132
+ export declare interface PixCheckoutProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
14133
+ /** The charge as the backend reports it — pair with {@link usePixCharge} to follow it. */
14134
+ charge: PixCharge;
14135
+ /** Rendered side of the QR in px. Default `220`. */
14136
+ qrSize?: number;
14137
+ labels?: Partial<Omit<PixCheckoutLabels, "states">> & {
14138
+ states?: Partial<PixCheckoutLabels["states"]>;
14139
+ };
14140
+ /** Formats the countdown. Default {@link formatPixRemaining}. */
14141
+ formatRemaining?: (ms: number) => string;
14142
+ /** Called after the copia-e-cola reaches the clipboard. */
14143
+ onCopied?: () => void;
14144
+ /** Rendered under the status, e.g. a "gerar novo Pix" button for a final state. */
14145
+ footer?: ReactNode;
14146
+ }
14147
+
13515
14148
  /** A pixel coordinate inside the plotting viewport. */
13516
14149
  export declare interface PixelPoint {
13517
14150
  x: number;
@@ -14911,8 +15544,11 @@ export declare interface ResumableUploadOptions {
14911
15544
  * It is read again before every chunk and every record write: when it
14912
15545
  * names someone else mid-run, the run stops with
14913
15546
  * {@link ResumableUploadSupersededError} (`"principal"`) before the new
14914
- * account's token reaches the previous one's upload URL. Without it, call
14915
- * `abort()` on the uploads in progress from `onSessionEnd`.
15547
+ * account's token reaches the previous one's upload URL. Without it,
15548
+ * `createLocalUploadStorage().clear()` from `onSessionEnd` stops the runs in
15549
+ * flight and, since 0.84.0, makes a paused handle start over with a fresh
15550
+ * `Idempotency-Key`; with a custom `storage`, call `abort()` on the uploads
15551
+ * in progress there instead.
14916
15552
  */
14917
15553
  getPrincipal?: () => string | number | null | undefined;
14918
15554
  /**
@@ -17356,10 +17992,61 @@ export declare interface TempestAuth<TUser, TCredentials> {
17356
17992
  /**
17357
17993
  * Refresh the access token (deduplicated across concurrent callers).
17358
17994
  *
17995
+ * When both the access token held and the one redeemed are JWTs with a
17996
+ * `sub` claim and the subjects differ, the redeemed credential — a refresh
17997
+ * cookie another sign-in replaced — belongs to another account. That is
17998
+ * an account switch, not a rotation: the held session ends with
17999
+ * `onSessionEnd` `"switch"`, the new one gets a lineage of its own and its
18000
+ * user is loaded, exactly as `login()` would; `refresh()` resolves with it
18001
+ * installed, and a `401` replay of the previous account's request rejects
18002
+ * with {@link SessionSupersededError} instead of going out as the new one
18003
+ * (#579). With opaque tokens there is no subject to compare, and the
18004
+ * redemption counts as a rotation — call `restore()` where a sign-in may
18005
+ * have happened outside `login()`.
18006
+ *
17359
18007
  * @throws {SessionSupersededError} When the session ended or changed while
17360
- * the refresh was in flight; its tokens were discarded.
18008
+ * the refresh was in flight; its tokens were discarded. That includes a
18009
+ * `logout()` or `login()` landing after the redemption of another
18010
+ * account and before the switch: it wins over the switch (#591). And a
18011
+ * `login()` still in flight when the redemption brought another account:
18012
+ * the explicit sign-in wins, the switch is discarded and, in body mode,
18013
+ * its refresh token revoked (#595).
17361
18014
  */
17362
18015
  refresh: () => Promise<void>;
18016
+ /**
18017
+ * Redeem the refresh credential as a **new sign-in**: whatever it signs in
18018
+ * replaces the session installed now, like `login()` with no credentials.
18019
+ *
18020
+ * For the point where the app knows a sign-in happened outside `login()`
18021
+ * — the OAuth or magic-link callback that set the refresh cookie. The
18022
+ * session held, if any, ends with `onSessionEnd` `"switch"` only once the
18023
+ * redemption succeeded, the new one gets a lineage of its own, and the
18024
+ * user is loaded (`parseUser`, then `mePath`). A failed redemption leaves
18025
+ * the held session untouched.
18026
+ *
18027
+ * `refresh()` cannot make that call on its own when tokens are opaque: a
18028
+ * rotation of the same account and another account's cookie look alike,
18029
+ * and comparing `mePath` users would cost a request per rotation and
18030
+ * reopen #544. So the boot keeps `refresh()` — a reload must not end the
18031
+ * session — and the callback uses this. Called where no sign-in happened,
18032
+ * it costs a needless switch: an upload bound to the session starts over.
18033
+ *
18034
+ * Two tabs restoring together redeem once (#594). The redemption holds an
18035
+ * origin-wide sign-in lock until the session it brought is installed, so a
18036
+ * tab that calls `restore()` meanwhile waits for it and adopts that
18037
+ * session — its own, if any, ends with `onSessionEnd` `"switch"` and
18038
+ * `elsewhere: true` — and a `refresh()` that waited behind it follows the
18039
+ * new session instead of redeeming the refresh token it spent. Until
18040
+ * 0.84.0 the waiting tab redeemed again: a spent token, which a backend
18041
+ * with reuse detection answers by revoking the whole family, or none at
18042
+ * all, since the restoring tab's teardown had already cleared it.
18043
+ *
18044
+ * @returns The user of the new session, or null.
18045
+ * @throws {SessionSupersededError} When a `logout()` or `login()` moved
18046
+ * the session while it was in flight; the new tokens are discarded. Also
18047
+ * when the other tab's sign-in it waited for left no session to adopt.
18048
+ */
18049
+ restore: () => Promise<TUser | null>;
17363
18050
  /** The current access token, or null. */
17364
18051
  getToken: () => string | null;
17365
18052
  /**
@@ -17382,8 +18069,36 @@ export declare interface TempestAuth<TUser, TCredentials> {
17382
18069
  * answered one constant for every account, and an upload bound by
17383
18070
  * `getToken: auth.getToken` was resumed by the next account restored the
17384
18071
  * same way.
18072
+ *
18073
+ * A `refresh()` that redeems another account while a session is installed
18074
+ * changes the key too, when JWT subjects tell the accounts apart; with
18075
+ * opaque tokens `restore()` is the call that does (#579). Until 0.83.0 such
18076
+ * a redemption kept the previous account's key.
17385
18077
  */
17386
18078
  sessionKey: () => string | null;
18079
+ /**
18080
+ * Whether the session this preset holds is settled — `false` while it is
18081
+ * still being decided (#596).
18082
+ *
18083
+ * It is `false` while a `login()`, a `restore()` or an account switch is
18084
+ * in flight (their user load included), and while a `refresh()` runs with
18085
+ * no token installed — the boot restore from a refresh cookie. It is
18086
+ * `true` otherwise, signed in or signed out: a signed-out answer is then
18087
+ * the real one, not "the restore has not answered yet".
18088
+ *
18089
+ * What it is for: a store that persists per-account data across boots
18090
+ * must not stamp it while the account is unknown. A cookie app reads
18091
+ * nobody signed in until its restore answers, and the persisted query
18092
+ * cache used to stamp the signed-in account's responses as anonymous in
18093
+ * that window, for the next signed-out boot to hydrate.
18094
+ * `persistQueryClientOffline({ auth })` reads it on its own.
18095
+ *
18096
+ * It says nothing about the user profile: a session restored by
18097
+ * `refresh()` installs a token and a `sessionKey()` without loading the
18098
+ * user. A principal read from the user is known only once that user is
18099
+ * there, which `persistQueryClientOffline` also checks.
18100
+ */
18101
+ isSessionKnown: () => boolean;
17387
18102
  /**
17388
18103
  * Stop following the other tabs: removes the `storage` listener this
17389
18104
  * preset adds to `window`. Idempotent.
@@ -18517,8 +19232,9 @@ export declare interface UploadProgressEvent {
18517
19232
  *
18518
19233
  * An `XMLHttpRequest` cannot refuse a redirect; see
18519
19234
  * {@link UploadWithProgressOptions.redirect} for what follows one, what the
18520
- * helper still refuses, and the `fetch` path that trades progress for never
18521
- * following.
19235
+ * helper still refuses, the `fetch` path that trades progress for never
19236
+ * following, and when that path is the default (fixed headers and no
19237
+ * `onProgress`, since 0.84.0).
18522
19238
  *
18523
19239
  * @returns The parsed JSON response, or the raw text when the response is not JSON.
18524
19240
  */
@@ -18574,30 +19290,41 @@ export declare interface UploadWithProgressOptions {
18574
19290
  */
18575
19291
  requestId?: () => string;
18576
19292
  /**
18577
- * What to do when the server answers with a redirect. Default `"follow"`.
19293
+ * What to do when the server answers with a redirect. When unset, the
19294
+ * helper picks: `"error"` when {@link headers} carry anything besides the
19295
+ * headers it exempts (`Authorization`, `X-Request-ID`, `Content-Type` and
19296
+ * `X-CSRF-Token`) **and** no {@link onProgress} was given, `"follow"`
19297
+ * otherwise (since 0.84.0). A value passed here always wins.
18578
19298
  *
18579
19299
  * - `"follow"` — the `XMLHttpRequest` path, with byte-level progress. The
18580
19300
  * browser follows every redirect and offers no way to stop it: measured
18581
- * in Chrome 150 (#570), a same-origin upload answered `301`/`302`/`303`/
18582
- * `307`/`308` towards another origin delivered `X-Api-Key` from
18583
- * {@link headers} and the SDK's own `X-CSRF-Token` there on all five, and
18584
- * the body on `307`/`308`; only `Authorization` was stripped. What this
18585
- * path does enforce (since 0.83.0): an answer from another origin than
18586
- * the one the request was sent to is never the result — it rejects with
19301
+ * in Chrome 150, and again in Chromium 153, Firefox 155 and WebKit 26.6
19302
+ * (#570), a same-origin upload answered `301`/`302`/`303`/`307`/`308`
19303
+ * towards another origin delivered `X-Api-Key` from {@link headers} and
19304
+ * the SDK's own `X-CSRF-Token` there on all five, and the body on
19305
+ * `307`/`308`; only `Authorization` was stripped. What this path does
19306
+ * enforce (since 0.83.0): an answer from another origin than the one the
19307
+ * request was sent to is never the result — it rejects with
18587
19308
  * `code: "REDIRECT_REFUSED"`, so that host cannot hand the app a URL to
18588
19309
  * store. Until 0.82.0 it resolved with the other host's body.
18589
19310
  * - `"error"` — goes out over `fetch` with `redirect: "manual"`, and a
18590
19311
  * redirect rejects with `code: "REDIRECT_REFUSED"` before anything is
18591
19312
  * sent to the other host. The cost: `fetch` reports no upload progress,
18592
- * so `onProgress` fires once, when the server confirms the whole body. A
19313
+ * so `onProgress` fires once, when the server confirms the whole body,
19314
+ * and a same-origin redirect (FastAPI's trailing-slash `307`) is refused
19315
+ * too — a browser hands it back opaque, with no readable `Location`. A
18593
19316
  * streamed `fetch` body would report progress, but Chrome refuses one
18594
19317
  * over HTTP/1.1 (`TypeError: Failed to fetch`, measured) and Firefox and
18595
19318
  * Safari do not support it.
18596
19319
  *
18597
- * Use `"error"` when {@link headers} carry a credential (an `X-Api-Key`) and
18598
- * the server behind `url` could redirect; sending the bearer through
18599
- * {@link getToken} keeps `"follow"` safe for it, because the browser strips
18600
- * `Authorization` on a cross-origin redirect.
19320
+ * Why the default depends on `onProgress`: progress is the only thing the
19321
+ * XHR path buys, and the leak is its price. A caller that asked for no
19322
+ * progress paid that price for nothing, so its fixed headers get the
19323
+ * treatment `createApiClient` (#560) and `createResumableUpload` (#568)
19324
+ * give theirs. A caller that wants progress keeps it, and the guarantee is
19325
+ * one `redirect: "error"` away. Sending the bearer through
19326
+ * {@link getToken} keeps `"follow"` safe for it, because the browser
19327
+ * strips `Authorization` on a cross-origin redirect.
18601
19328
  */
18602
19329
  redirect?: "follow" | "error";
18603
19330
  }
@@ -20030,6 +20757,107 @@ export declare interface UseMediaPermissionResult {
20030
20757
  */
20031
20758
  export declare function useMediaQuery(query: string): boolean;
20032
20759
 
20760
+ /**
20761
+ * Card tokenization with MercadoPago.js **Secure Fields**, plus installments by BIN.
20762
+ *
20763
+ * The card number, expiry and CVV are typed into iframes served by Mercado Pago,
20764
+ * so they never exist in this page's DOM, in React state, in a callback argument
20765
+ * or in a log line — not even transiently. That is the property the PCI DSS
20766
+ * scoping depends on: a page that renders its own `<input>` for the number and
20767
+ * calls `createCardToken` with it has handled cardholder data and is in the
20768
+ * heavier SAQ A-EP scope, however quickly it discards the value. The backend
20769
+ * never sees the card either: it receives the token, the brand and the
20770
+ * installments, which is exactly `CardChargeRequest`.
20771
+ *
20772
+ * The only digits the hook learns are the BIN (first 6–8), which Mercado Pago's
20773
+ * `binChange` event exposes precisely so the page can quote installments; it is
20774
+ * used for the lookup and not returned. Installment options come from the
20775
+ * provider with its own `recommended_message`, because interest starts at 2x
20776
+ * (measured in the sandbox) and the total the payer sees has to be the
20777
+ * provider's number, not one recomputed here.
20778
+ *
20779
+ * The containers must be in the DOM when the hook's effect runs — render the
20780
+ * three empty elements in the same component. The fields are created once per
20781
+ * `publicKey`; changing the containers, locale or loader afterwards does not
20782
+ * remount them. A new `publicKey` remounts empty fields and forgets the previous
20783
+ * BIN, brand and quote with them.
20784
+ *
20785
+ * `tokenize` binds the token to the quote: Mercado Pago's token carries
20786
+ * `first_six_digits`, and a token whose digits are not the quoted BIN is
20787
+ * refused. `binChange` is debounced inside the iframe, so a payer who swaps the
20788
+ * card number and submits at once would otherwise send the new card with the
20789
+ * old card's brand and installments. A token response without
20790
+ * `first_six_digits` is not refused — there is nothing to compare — and the
20791
+ * backend and Mercado Pago still validate the brand on the charge.
20792
+ *
20793
+ * @tempest-limits empty-catch — `unmount()` throws when MercadoPago.js already
20794
+ * tore the iframe down (a container removed by React first). The cleanup has
20795
+ * nothing left to undo in that case and nowhere useful to report it.
20796
+ *
20797
+ * @param options - Public key, amount, container ids and an injectable loader.
20798
+ * @returns Field status, brand, installment options and `tokenize`.
20799
+ *
20800
+ * @example
20801
+ * const card = useMercadoPagoCard({
20802
+ * publicKey: import.meta.env.VITE_MP_PUBLIC_KEY,
20803
+ * amountCents: 10964,
20804
+ * containers: { cardNumber: "mp-number", expirationDate: "mp-expiry", securityCode: "mp-cvv" },
20805
+ * });
20806
+ * const { token, payment_method_id, installments } = await card.tokenize({
20807
+ * cardholderName: "APRO",
20808
+ * installments: 1,
20809
+ * identificationType: "CPF",
20810
+ * identificationNumber: "12345678909",
20811
+ * });
20812
+ */
20813
+ export declare function useMercadoPagoCard(options: UseMercadoPagoCardOptions): UseMercadoPagoCardResult;
20814
+
20815
+ /** Options for {@link useMercadoPagoCard}. */
20816
+ export declare interface UseMercadoPagoCardOptions {
20817
+ /**
20818
+ * The application's **Public Key** — never the access token. It is meant to
20819
+ * be public: it can only tokenize, and the token is useless without the
20820
+ * access token that stays on the backend.
20821
+ */
20822
+ publicKey: string;
20823
+ /** The price in cents, used to quote installments. */
20824
+ amountCents: number;
20825
+ /** Ids of the empty elements the card number, expiry and CVV iframes mount into. */
20826
+ containers: MercadoPagoCardContainers;
20827
+ /** MercadoPago.js locale. Default `"pt-BR"`. */
20828
+ locale?: string;
20829
+ /** Per-field options (placeholder, inline style). */
20830
+ fieldOptions?: Partial<Record<MercadoPagoFieldType, MercadoPagoFieldOptions>>;
20831
+ /** Loads the constructor. Default {@link loadMercadoPago}; tests pass a fake. */
20832
+ load?: () => Promise<MercadoPagoConstructor>;
20833
+ }
20834
+
20835
+ /** Return value of {@link useMercadoPagoCard}. */
20836
+ export declare interface UseMercadoPagoCardResult {
20837
+ /** `"ready"` once all three fields are mounted. */
20838
+ status: MercadoPagoCardStatus;
20839
+ /** Why loading or mounting failed. */
20840
+ error: Error | null;
20841
+ /** Brand detected from the BIN, or `null` until the payer types enough digits. */
20842
+ paymentMethodId: string | null;
20843
+ /** Installment choices for the current BIN and amount; empty until known. */
20844
+ installmentOptions: CardInstallmentOption[];
20845
+ /** `true` while the installments for a new BIN are being fetched. */
20846
+ installmentsLoading: boolean;
20847
+ /** Why the installment lookup failed, if it did. */
20848
+ installmentsError: Error | null;
20849
+ /**
20850
+ * Ask Mercado Pago for a card token. Throws when the fields are not ready,
20851
+ * the BIN has not been identified, or `installments` is not one of the
20852
+ * offered options — each of which would otherwise surface later as an
20853
+ * opaque `400` from the backend. Also throws, after the token is created,
20854
+ * when the token's `first_six_digits` is not the BIN the brand and
20855
+ * installments were quoted for: the payer changed the card number after the
20856
+ * quote, and charging it would send one card with another card's brand.
20857
+ */
20858
+ tokenize: (input: CardTokenizeInput) => Promise<CardTokenResult>;
20859
+ }
20860
+
20033
20861
  /**
20034
20862
  * Acquire a microphone `MediaStream`, classified errors included, and release it
20035
20863
  * properly.
@@ -20663,6 +21491,62 @@ export declare interface UsePasskeySignInResult<TResult> extends PasskeyCapabili
20663
21491
  reset: () => void;
20664
21492
  }
20665
21493
 
21494
+ /**
21495
+ * Follow a Pix charge until the backend says it is final.
21496
+ *
21497
+ * The browser never decides that a Pix was paid: there is no client-side signal
21498
+ * that could prove it, and a screen that infers "paid" from a countdown or a
21499
+ * copy click is a screen that ships goods for free. This hook only relays what
21500
+ * the app's `refresh`/`subscribe` report, and stops polling once the status is
21501
+ * final (`paid`, `expired`, `cancelled`, `refunded`, `charged_back`, `failed`).
21502
+ *
21503
+ * Polling is sequential — the next request starts `intervalMs` after the
21504
+ * previous one settled — so a slow backend is never hit by overlapping reads.
21505
+ * A failed read keeps the last good charge and is exposed as `error`; the poll
21506
+ * goes on, because a dropped request is not a payment state.
21507
+ *
21508
+ * An update for another `provider` or `provider_charge_id` is ignored, and a
21509
+ * `paid` charge only moves on to `refunded` or `charged_back` — a late
21510
+ * `expired` never replaces it. Passing a charge with a different `provider` or
21511
+ * `provider_charge_id` restarts the follow.
21512
+ *
21513
+ * @param initial - The charge as created.
21514
+ * @param options - `refresh`, `subscribe` and the poll period.
21515
+ * @returns The latest charge and the last read error.
21516
+ *
21517
+ * @example
21518
+ * const { charge } = usePixCharge(created, {
21519
+ * refresh: (signal) => api.get<PixCharge>(`/api/pix/${created.provider_charge_id}`, { signal }),
21520
+ * });
21521
+ * return <PixCheckout charge={charge} />;
21522
+ */
21523
+ export declare function usePixCharge(initial: PixCharge, options?: UsePixChargeOptions): UsePixChargeResult;
21524
+
21525
+ /** Options for {@link usePixCharge}. */
21526
+ export declare interface UsePixChargeOptions {
21527
+ /**
21528
+ * Re-reads the charge from **your backend** — which re-reads it from the
21529
+ * provider. Called every `intervalMs` until the charge is final. The signal
21530
+ * aborts when the component unmounts or the charge changes.
21531
+ */
21532
+ refresh?: (signal: AbortSignal) => Promise<PixCharge>;
21533
+ /**
21534
+ * Pushes updates instead of polling — an SSE stream, a WebSocket. Receives
21535
+ * the emitter and returns its own cleanup. Can be combined with `refresh`.
21536
+ */
21537
+ subscribe?: (emit: (charge: PixCharge) => void) => () => void;
21538
+ /** Poll period in ms. Default `5000`. */
21539
+ intervalMs?: number;
21540
+ }
21541
+
21542
+ /** Return value of {@link usePixCharge}. */
21543
+ export declare interface UsePixChargeResult {
21544
+ /** The latest charge the backend reported. */
21545
+ charge: PixCharge;
21546
+ /** The last `refresh` failure, cleared by the next success. Polling continues after it. */
21547
+ error: Error | null;
21548
+ }
21549
+
20666
21550
  /**
20667
21551
  * Poll an async factory on a fixed interval. Skips overlapping requests if a
20668
21552
  * prior call has not finished. Pause via `disabled` or `stopWhen`.