tempest-react-sdk 0.81.0 → 0.83.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/README.md +9 -10
- package/bin/create-tempest-app.e2e.test.mjs +31 -0
- package/bin/create-tempest-app.mjs +11 -1
- package/bin/lib/doctor/doctor.e2e.test.mjs +29 -0
- package/bin/lib/doctor/vitest.mjs +120 -0
- package/bin/lib/doctor/vitest.test.mjs +139 -0
- package/bin/lib/fs/contain.mjs +7 -0
- package/bin/lib/openapi/escape.mjs +68 -4
- package/bin/lib/openapi/generate.hostile.test.mjs +228 -0
- package/bin/lib/openapi/generate.mjs +119 -15
- package/bin/lib/openapi/pattern-risk.mjs +134 -0
- package/bin/lib/openapi/pattern-risk.test.mjs +45 -0
- package/bin/tempest-gen.test.mjs +100 -0
- package/bin/tempest.mjs +24 -8
- package/dist/access/use-can.cjs +1 -1
- package/dist/access/use-can.cjs.map +1 -1
- package/dist/access/use-can.js +25 -28
- package/dist/access/use-can.js.map +1 -1
- package/dist/auth/create-tempest-auth.cjs +1 -1
- package/dist/auth/create-tempest-auth.cjs.map +1 -1
- package/dist/auth/create-tempest-auth.js +189 -143
- package/dist/auth/create-tempest-auth.js.map +1 -1
- package/dist/auth/session-identity.cjs +2 -0
- package/dist/auth/session-identity.cjs.map +1 -0
- package/dist/auth/session-identity.js +12 -0
- package/dist/auth/session-identity.js.map +1 -0
- package/dist/br/boleto.cjs.map +1 -1
- package/dist/br/boleto.js.map +1 -1
- package/dist/components/AuthForm/AuthLinks.cjs +1 -1
- package/dist/components/AuthForm/AuthLinks.cjs.map +1 -1
- package/dist/components/AuthForm/AuthLinks.js +18 -15
- package/dist/components/AuthForm/AuthLinks.js.map +1 -1
- package/dist/components/AuthPage/AuthPage.cjs +1 -1
- package/dist/components/AuthPage/AuthPage.cjs.map +1 -1
- package/dist/components/AuthPage/AuthPage.js +58 -52
- package/dist/components/AuthPage/AuthPage.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.cjs +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.cjs.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js +22 -21
- package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/Button/Button.cjs +1 -1
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.js +41 -40
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Chat/ChatAttachments.cjs +1 -1
- package/dist/components/Chat/ChatAttachments.cjs.map +1 -1
- package/dist/components/Chat/ChatAttachments.js +38 -38
- package/dist/components/Form/Form.cjs +1 -1
- package/dist/components/Form/Form.cjs.map +1 -1
- package/dist/components/Form/Form.js +30 -32
- package/dist/components/Form/Form.js.map +1 -1
- package/dist/components/Layout/Layout.cjs +1 -1
- package/dist/components/Layout/Layout.cjs.map +1 -1
- package/dist/components/Layout/Layout.js +25 -24
- package/dist/components/Layout/Layout.js.map +1 -1
- package/dist/components/Layout/gap.cjs +2 -0
- package/dist/components/Layout/gap.cjs.map +1 -0
- package/dist/components/Layout/gap.js +15 -0
- package/dist/components/Layout/gap.js.map +1 -0
- package/dist/components/NavigationMenu/NavigationMenu.cjs +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.cjs.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.js +71 -70
- package/dist/components/NavigationMenu/NavigationMenu.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/components/Sidebar/SidebarEntry.cjs +1 -1
- package/dist/components/Sidebar/SidebarEntry.cjs.map +1 -1
- package/dist/components/Sidebar/SidebarEntry.js +30 -29
- package/dist/components/Sidebar/SidebarEntry.js.map +1 -1
- package/dist/data/create-data-provider.cjs +1 -1
- package/dist/data/create-data-provider.cjs.map +1 -1
- package/dist/data/create-data-provider.js +1 -2
- package/dist/data/create-data-provider.js.map +1 -1
- package/dist/forms/validate-form.cjs +1 -1
- package/dist/forms/validate-form.cjs.map +1 -1
- package/dist/forms/validate-form.js +6 -1
- package/dist/forms/validate-form.js.map +1 -1
- package/dist/forms/zod-resolver.cjs +1 -1
- package/dist/forms/zod-resolver.cjs.map +1 -1
- package/dist/forms/zod-resolver.js +8 -3
- package/dist/forms/zod-resolver.js.map +1 -1
- package/dist/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +90 -72
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/credential-scope.cjs +1 -1
- package/dist/http/credential-scope.cjs.map +1 -1
- package/dist/http/credential-scope.js +33 -9
- package/dist/http/credential-scope.js.map +1 -1
- package/dist/http/presigned-post.cjs.map +1 -1
- package/dist/http/presigned-post.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +167 -112
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/upload-with-progress.cjs +1 -1
- package/dist/http/upload-with-progress.cjs.map +1 -1
- package/dist/http/upload-with-progress.js +100 -44
- package/dist/http/upload-with-progress.js.map +1 -1
- package/dist/oauth/GoogleSignIn.cjs +1 -1
- package/dist/oauth/GoogleSignIn.cjs.map +1 -1
- package/dist/oauth/GoogleSignIn.js +5 -4
- package/dist/oauth/GoogleSignIn.js.map +1 -1
- package/dist/offline/create-offline-sync.cjs +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js +87 -69
- package/dist/offline/create-offline-sync.js.map +1 -1
- package/dist/query/offline-persistence.cjs +1 -1
- package/dist/query/offline-persistence.cjs.map +1 -1
- package/dist/query/offline-persistence.js +67 -44
- package/dist/query/offline-persistence.js.map +1 -1
- package/dist/sse/create-event-stream.cjs +1 -1
- package/dist/sse/create-event-stream.cjs.map +1 -1
- package/dist/sse/create-event-stream.js +48 -41
- package/dist/sse/create-event-stream.js.map +1 -1
- package/dist/sse/ticket-event-stream.cjs +1 -1
- package/dist/sse/ticket-event-stream.cjs.map +1 -1
- package/dist/sse/ticket-event-stream.js +48 -19
- package/dist/sse/ticket-event-stream.js.map +1 -1
- package/dist/sse/use-event-stream.cjs +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/sse/use-event-stream.js +19 -14
- package/dist/sse/use-event-stream.js.map +1 -1
- package/dist/sw/background-sync.cjs +1 -1
- package/dist/sw/background-sync.cjs.map +1 -1
- package/dist/sw/background-sync.js +10 -8
- package/dist/sw/background-sync.js.map +1 -1
- package/dist/sw/cache.cjs +1 -1
- package/dist/sw/cache.cjs.map +1 -1
- package/dist/sw/cache.js +111 -55
- package/dist/sw/cache.js.map +1 -1
- package/dist/sw/create-push-handler.cjs +1 -1
- package/dist/sw/create-push-handler.cjs.map +1 -1
- package/dist/sw/create-push-handler.js +20 -10
- package/dist/sw/create-push-handler.js.map +1 -1
- package/dist/sw.d.ts +65 -14
- package/dist/tabular/compact.cjs +1 -1
- package/dist/tabular/compact.cjs.map +1 -1
- package/dist/tabular/compact.js +35 -16
- package/dist/tabular/compact.js.map +1 -1
- package/dist/tabular/manifest.cjs +1 -1
- package/dist/tabular/manifest.cjs.map +1 -1
- package/dist/tabular/manifest.js +33 -15
- package/dist/tabular/manifest.js.map +1 -1
- package/dist/tabular.d.ts +11 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +543 -70
- package/dist/tempest-react-sdk.js +224 -224
- package/dist/theme/initial-theme.cjs +4 -4
- package/dist/theme/initial-theme.cjs.map +1 -1
- package/dist/theme/initial-theme.js +8 -5
- package/dist/theme/initial-theme.js.map +1 -1
- package/dist/utils/compressed-storage.cjs +1 -1
- package/dist/utils/compressed-storage.cjs.map +1 -1
- package/dist/utils/compressed-storage.js +13 -7
- package/dist/utils/compressed-storage.js.map +1 -1
- package/dist/utils/objects.cjs +1 -1
- package/dist/utils/objects.cjs.map +1 -1
- package/dist/utils/objects.js +13 -7
- package/dist/utils/objects.js.map +1 -1
- package/dist/utils/safe-url.cjs +1 -1
- package/dist/utils/safe-url.cjs.map +1 -1
- package/dist/utils/safe-url.js +4 -1
- package/dist/utils/safe-url.js.map +1 -1
- package/dist/vite/base-url.cjs +1 -1
- package/dist/vite/base-url.cjs.map +1 -1
- package/dist/vite/base-url.js +5 -1
- package/dist/vite/base-url.js.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.js +96 -31
- package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs +2 -2
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js +32 -16
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.d.ts +63 -12
- package/dist/vite.js +4 -4
- package/dist/webrtc/peer-mesh.cjs +1 -1
- package/dist/webrtc/peer-mesh.cjs.map +1 -1
- package/dist/webrtc/peer-mesh.js +7 -1
- package/dist/webrtc/peer-mesh.js.map +1 -1
- package/dist/ws/create-web-socket.cjs +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js +77 -61
- package/dist/ws/create-web-socket.js.map +1 -1
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +4 -3
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +1 -1
- package/template-pwa/src/pwa.tsx +42 -0
- package/template-pwa/src/sw.ts +5 -4
|
@@ -966,7 +966,20 @@ export declare interface ApiClientConfig {
|
|
|
966
966
|
* without it, and is exposed the same way.
|
|
967
967
|
*/
|
|
968
968
|
csrf?: boolean | CsrfOptions;
|
|
969
|
-
/**
|
|
969
|
+
/**
|
|
970
|
+
* Default headers merged into every request inside the credential scope.
|
|
971
|
+
*
|
|
972
|
+
* Treated as a credential since 0.82.0 — an `X-Api-Key` set once here is as
|
|
973
|
+
* much a secret as the bearer — so they go only to `baseURL`'s origin and
|
|
974
|
+
* {@link trustedOrigins}. A redirect would move them past that check, and
|
|
975
|
+
* unlike `Authorization` no browser strips them on a cross-origin hop
|
|
976
|
+
* (measured in Chrome 150, #554). So while this is non-empty, an in-scope
|
|
977
|
+
* request goes out with `redirect: "manual"`, and a redirect answering it
|
|
978
|
+
* is thrown as a `TempestApiError` with `code: "REDIRECT_REFUSED"` — the
|
|
979
|
+
* browser hides the `Location`, so the same-origin case cannot be told
|
|
980
|
+
* apart and followed by hand. Call the final URL (FastAPI's trailing-slash
|
|
981
|
+
* `307` is the usual source), or pass `redirect: "follow"` on the call.
|
|
982
|
+
*/
|
|
970
983
|
headers?: Record<string, string>;
|
|
971
984
|
/** Optional fetch implementation (defaults to globalThis.fetch). */
|
|
972
985
|
fetcher?: typeof fetch;
|
|
@@ -1998,7 +2011,11 @@ export declare interface AuthPageAside {
|
|
|
1998
2011
|
|
|
1999
2012
|
/** The back action, as an object when the label or the behavior is not the default. */
|
|
2000
2013
|
export declare interface AuthPageBackAction {
|
|
2001
|
-
/**
|
|
2014
|
+
/**
|
|
2015
|
+
* Route to navigate to, rendered as a router `Link`. Passes through
|
|
2016
|
+
* `safeLinkUrl`: a destination it rejects is dropped, leaving the button with
|
|
2017
|
+
* `onClick` or, without one, no back action at all.
|
|
2018
|
+
*/
|
|
2002
2019
|
to?: string;
|
|
2003
2020
|
/** Visible label (and accessible name). Default `"Voltar"`. */
|
|
2004
2021
|
label?: string;
|
|
@@ -2642,6 +2659,12 @@ export declare interface BreadcrumbItem {
|
|
|
2642
2659
|
* Hierarchical navigation breadcrumbs. The last item is rendered as plain
|
|
2643
2660
|
* text with `aria-current="page"`. Items with neither `href` nor `onClick`
|
|
2644
2661
|
* also render as text (intermediate but non-clickable).
|
|
2662
|
+
*
|
|
2663
|
+
* Each `href` is vetted with `safeLinkUrl`'s allowlist: an item whose URL uses a scheme
|
|
2664
|
+
* outside `http:`/`https:`/`mailto:`/`tel:`/`sms:` loses the `href`, and renders
|
|
2665
|
+
* as text unless it also has an `onClick`. A trail built from API data — the
|
|
2666
|
+
* folder names of a document tree — would otherwise put a clickable
|
|
2667
|
+
* `javascript:` link on the page under React 18, which writes it verbatim.
|
|
2645
2668
|
*/
|
|
2646
2669
|
export declare function Breadcrumbs({ items, separator, className }: BreadcrumbsProps): JSX.Element;
|
|
2647
2670
|
|
|
@@ -2789,6 +2812,13 @@ export declare function buildOpenInChromeIntent(): string | null;
|
|
|
2789
2812
|
* link gets `aria-disabled="true"`, `role="link"`, `tabIndex={-1}`, no `href`, and
|
|
2790
2813
|
* its click and middle-click cancelled.
|
|
2791
2814
|
*
|
|
2815
|
+
* The `href` is vetted first, with `safeLinkUrl`'s allowlist: `http:`, `https:`, `mailto:`,
|
|
2816
|
+
* `tel:`, `sms:` and relative URLs pass, anything else renders as the same inert,
|
|
2817
|
+
* `aria-disabled` link. React 19 blocks a `javascript:` href but the peer range
|
|
2818
|
+
* admits React 18, which writes it verbatim (#447), and a CTA built from API data
|
|
2819
|
+
* should not need the app to remember that. A link to a custom scheme (`whatsapp:`,
|
|
2820
|
+
* an app deep link) goes through {@link ButtonSlot} with the app's own `<a>`.
|
|
2821
|
+
*
|
|
2792
2822
|
* To style another element — a react-router `Link` — use {@link ButtonSlot}. It is
|
|
2793
2823
|
* a separate component, not an `asChild` prop, so an app that never uses it does
|
|
2794
2824
|
* not ship the prop merge and ref composition it needs.
|
|
@@ -4177,7 +4207,21 @@ export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value
|
|
|
4177
4207
|
* destination of a credentialed request could come from a value read off the
|
|
4178
4208
|
* network. A request to another origin still goes out; it goes without the
|
|
4179
4209
|
* header, and a development build says so once. Declare the exceptions in
|
|
4180
|
-
* {@link ApiClientConfig.trustedOrigins}.
|
|
4210
|
+
* {@link ApiClientConfig.trustedOrigins}. Since 0.82.0 the static
|
|
4211
|
+
* {@link ApiClientConfig.headers} follow the same scope, and a `401` from
|
|
4212
|
+
* outside it is thrown without `refresh` or `onUnauthorized` — it answered a
|
|
4213
|
+
* request that never carried this session's credential.
|
|
4214
|
+
*
|
|
4215
|
+
* **Redirects.** The scope is checked against the URL the request starts at;
|
|
4216
|
+
* where a redirect then goes is the transport's call. For `Authorization` that
|
|
4217
|
+
* is safe: browsers strip it on a cross-origin redirect, measured in Chrome 150
|
|
4218
|
+
* for `fetch` and XHR on `301`/`302`/`303`/`307`/`308` (#554). They strip
|
|
4219
|
+
* nothing else, so a request carrying the static {@link ApiClientConfig.headers}
|
|
4220
|
+
* goes out with `redirect: "manual"`, and a redirect answering it is thrown as a
|
|
4221
|
+
* {@link TempestApiError} with `code: "REDIRECT_REFUSED"` instead of being
|
|
4222
|
+
* followed. It cannot be followed by hand: a browser's manual redirect is an
|
|
4223
|
+
* opaque response whose `Location` is unreadable. A `redirect` set on the call
|
|
4224
|
+
* always wins.
|
|
4181
4225
|
*
|
|
4182
4226
|
* **CSRF** is off unless you set `csrf`. With it, every unsafe request (anything
|
|
4183
4227
|
* but `GET`/`HEAD`/`OPTIONS`/`TRACE`) echoes the `csrf_token` cookie in an
|
|
@@ -4505,7 +4549,13 @@ export declare function createDataProvider(client: ApiClient, options?: DataProv
|
|
|
4505
4549
|
*
|
|
4506
4550
|
* When `url` is a function it is called before every connection, so a
|
|
4507
4551
|
* reconnect presents a fresh credential instead of the one that expired. A
|
|
4508
|
-
* resolution still pending when `close()` or `reconnect()` runs is discarded
|
|
4552
|
+
* resolution still pending when `close()` or `reconnect()` runs is discarded, and
|
|
4553
|
+
* one that has not started yet is never made: a stream closed in the same tick
|
|
4554
|
+
* it was created asks for no URL — no ticket request, for the ticket stream.
|
|
4555
|
+
*
|
|
4556
|
+
* Pass `sessionKey` to bind the stream to the session it opened under: once
|
|
4557
|
+
* the key changes, no frame of the previous session reaches `onMessage`, and
|
|
4558
|
+
* the stream reconnects for the new one.
|
|
4509
4559
|
*
|
|
4510
4560
|
* @param url - Full SSE endpoint URL, or a function returning it per connection.
|
|
4511
4561
|
* @param options - Stream configuration and callbacks.
|
|
@@ -4573,6 +4623,30 @@ export declare interface CreateEventStreamOptions<T> {
|
|
|
4573
4623
|
* URL that never resolved never had an `EventSource`.
|
|
4574
4624
|
*/
|
|
4575
4625
|
onUrlError?: (error: unknown) => void;
|
|
4626
|
+
/**
|
|
4627
|
+
* Read the current session key; the stream belongs to the session that was
|
|
4628
|
+
* current when it connected.
|
|
4629
|
+
*
|
|
4630
|
+
* The server cannot end the stream for you. The `tempest-fastapi-sdk` SSE
|
|
4631
|
+
* router checks the ticket only when the stream opens, and neither logout
|
|
4632
|
+
* nor refresh-token revocation touches an open stream: it lives until the
|
|
4633
|
+
* client leaves. So a tab that switches from user A to user B without
|
|
4634
|
+
* closing the stream keeps receiving A's events under B.
|
|
4635
|
+
*
|
|
4636
|
+
* With this set, the key is read when each connection starts, again when
|
|
4637
|
+
* its URL resolved, and before every frame is delivered. A frame that
|
|
4638
|
+
* arrives after the key changed is dropped, never delivered, and the stream
|
|
4639
|
+
* reconnects for the session now current — with a fresh ticket, for the
|
|
4640
|
+
* ticket stream. A URL resolved while the key changed is discarded the same
|
|
4641
|
+
* way, since the ticket inside it may belong to either session.
|
|
4642
|
+
*
|
|
4643
|
+
* The check runs when a frame arrives: a stream that stays quiet holds its
|
|
4644
|
+
* connection until the next frame or until `close()`. The hook form closes
|
|
4645
|
+
* it as soon as the key changes.
|
|
4646
|
+
*
|
|
4647
|
+
* Keys are compared with `Object.is`. Leave it out and nothing changes.
|
|
4648
|
+
*/
|
|
4649
|
+
sessionKey?: () => SessionKey;
|
|
4576
4650
|
/**
|
|
4577
4651
|
* Whether a URL-resolution failure is worth another attempt. Default: always.
|
|
4578
4652
|
*
|
|
@@ -5309,7 +5383,7 @@ export declare interface CreateRefreshQueueOptions {
|
|
|
5309
5383
|
* | --- | --- | --- |
|
|
5310
5384
|
* | Create | `POST {endpoint}` + `Upload-Length`, `Upload-Metadata`, `Idempotency-Key` | `201` + `Location` (the upload URL, absolute or endpoint-relative) |
|
|
5311
5385
|
* | Probe | `HEAD {uploadUrl}` | `200`/`204` + `Upload-Offset` |
|
|
5312
|
-
* | Write | `PATCH {uploadUrl}` + `Upload-Offset`, `Content-Type: application/offset+octet-stream`, chunk body | `204` + the new `Upload-Offset
|
|
5386
|
+
* | Write | `PATCH {uploadUrl}` + `Upload-Offset`, `Content-Type: application/offset+octet-stream`, chunk body | `204` + the new `Upload-Offset`, past the one sent; `409` when the offset does not match |
|
|
5313
5387
|
* | Discard | `DELETE {uploadUrl}` | `204` |
|
|
5314
5388
|
*
|
|
5315
5389
|
* ## The failure that actually happens
|
|
@@ -5526,8 +5600,13 @@ export declare interface CreateStorePersistOptions<T> {
|
|
|
5526
5600
|
* elsewhere ends the session here too, with `onSessionEnd` told it happened
|
|
5527
5601
|
* `elsewhere`. Before 0.81.0 a tab left open after logout kept account A and,
|
|
5528
5602
|
* on its next `401`, redeemed account B's refresh token from the shared
|
|
5529
|
-
* storage, persisting `{ user: A, token: B }` (#524).
|
|
5530
|
-
*
|
|
5603
|
+
* storage, persisting `{ user: A, token: B }` (#524). Whether the stored
|
|
5604
|
+
* session is the held one is decided by a **session lineage** that `login()`
|
|
5605
|
+
* mints and every rotation keeps — not by comparing users, which took two
|
|
5606
|
+
* sign-ins whose user had not loaded yet for the same account (#544). Two tabs
|
|
5607
|
+
* 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.
|
|
5531
5610
|
*
|
|
5532
5611
|
* Refreshes are collapsed per rotation, not just per overlap: a `401` whose
|
|
5533
5612
|
* request left with a token that has since been replaced in the same session
|
|
@@ -5593,9 +5672,14 @@ export declare interface CreateTempestAuthOptions<TUser> {
|
|
|
5593
5672
|
* while it is in flight waits for it, because the logout response clears
|
|
5594
5673
|
* the auth cookies and would otherwise clear the new account's.
|
|
5595
5674
|
*
|
|
5596
|
-
*
|
|
5597
|
-
*
|
|
5598
|
-
*
|
|
5675
|
+
* An explicit `logout()` revokes, and so does a `"switch"` in body mode:
|
|
5676
|
+
* the replaced session's refresh token is still in the client's hands, and
|
|
5677
|
+
* the tempest-fastapi-sdk revokes by rotation family, so the session the
|
|
5678
|
+
* new login opened is untouched even for the same user. Before 0.82.0 a
|
|
5679
|
+
* switch revoked nothing and the replaced token stayed redeemable until it
|
|
5680
|
+
* expired. A `"switch"` in cookie mode does not revoke — the cookie jar
|
|
5681
|
+
* already holds the new account's cookie — and on `"expired"` the server
|
|
5682
|
+
* has already refused the session.
|
|
5599
5683
|
*
|
|
5600
5684
|
* Overlapping sign-outs each send their own revocation, and `login()` waits
|
|
5601
5685
|
* for all of them — at most 10 seconds, so one that
|
|
@@ -5806,9 +5890,23 @@ export declare interface CreateThemeOptions {
|
|
|
5806
5890
|
* cookie) on the ticket request, and the ticket in the URL opens that stream
|
|
5807
5891
|
* and nothing else.
|
|
5808
5892
|
*
|
|
5893
|
+
* With the `api` of `createTempestAuth` as `client` and no `sessionKey`, the
|
|
5894
|
+
* stream follows that preset's session (since 0.82.0): it closes the moment
|
|
5895
|
+
* the session is replaced or ends, reopens with a fresh ticket for the next
|
|
5896
|
+
* one, stays closed while nobody is signed in, and ignores token rotation.
|
|
5897
|
+
* Any other client binds only through `sessionKey`, checked per frame.
|
|
5898
|
+
*
|
|
5899
|
+
* @example
|
|
5900
|
+
* const stream = createTicketEventStream<Notification>({
|
|
5901
|
+
* client: auth.api,
|
|
5902
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
5903
|
+
* });
|
|
5904
|
+
*
|
|
5809
5905
|
* @example
|
|
5906
|
+
* // A client createTempestAuth did not build
|
|
5810
5907
|
* const stream = createTicketEventStream<Notification>({
|
|
5811
5908
|
* client: api,
|
|
5909
|
+
* sessionKey: () => useAuthStore.getState().user?.id ?? null,
|
|
5812
5910
|
* onMessage: ({ data }) => addNotification(data),
|
|
5813
5911
|
* onUrlError: (error) => toast.error(describeApiError(error)),
|
|
5814
5912
|
* });
|
|
@@ -5992,6 +6090,24 @@ export declare interface CreateWebSocketOptions<T> {
|
|
|
5992
6090
|
queueWhileClosed?: boolean;
|
|
5993
6091
|
/** Cap on buffered payloads when `queueWhileClosed` is on. Default: 100. */
|
|
5994
6092
|
maxQueuedMessages?: number;
|
|
6093
|
+
/**
|
|
6094
|
+
* Who is signed in right now — a stable, non-secret id such as the user id;
|
|
6095
|
+
* `null`/`undefined` when nobody is. Read when a payload is buffered by
|
|
6096
|
+
* `queueWhileClosed` and again when the buffer drains on the next open: a
|
|
6097
|
+
* payload goes out only while the same principal is signed in, and is
|
|
6098
|
+
* dropped otherwise.
|
|
6099
|
+
*
|
|
6100
|
+
* The URL and the protocols are fixed for the controller's life, so a socket
|
|
6101
|
+
* that authenticates by cookie re-handshakes as whoever is signed in at
|
|
6102
|
+
* reconnect time. Without this, a frame buffered by one account during the
|
|
6103
|
+
* backoff was sent on the reconnect under the next account's cookie when the
|
|
6104
|
+
* app did not `close()` the socket on logout (#531).
|
|
6105
|
+
*
|
|
6106
|
+
* Read synchronously. A non-string, non-number value (the `Promise` of an
|
|
6107
|
+
* `async` getter) or a getter that throws reads as nobody. Default: no
|
|
6108
|
+
* owner check.
|
|
6109
|
+
*/
|
|
6110
|
+
getPrincipal?: () => string | number | null | undefined;
|
|
5995
6111
|
/** Parse incoming frames. Default: JSON with raw-string fallback. */
|
|
5996
6112
|
parser?: (raw: string) => T;
|
|
5997
6113
|
/**
|
|
@@ -6794,10 +6910,18 @@ export declare function decodeJWT(token: string): DecodedJWT;
|
|
|
6794
6910
|
* compression was enabled — or by a write that fell back after `gzipSync`
|
|
6795
6911
|
* failed — still read back.
|
|
6796
6912
|
*
|
|
6913
|
+
* The output size is bounded before anything is inflated. fflate sizes its
|
|
6914
|
+
* output buffer from the gzip trailer (`ISIZE`) and never grows it — measured: a
|
|
6915
|
+
* 1 MB payload whose trailer claims 10 bytes inflates to exactly 10 — so
|
|
6916
|
+
* refusing a trailer above {@link MAX_DECOMPRESSED_BYTES} bounds the allocation,
|
|
6917
|
+
* whatever the trailer says about the real data. A corrupted or hostile value
|
|
6918
|
+
* fails fast instead of taking the tab's memory.
|
|
6919
|
+
*
|
|
6797
6920
|
* @typeParam T - The expected value shape.
|
|
6798
6921
|
* @param raw - The stored string.
|
|
6799
6922
|
* @returns The decoded value.
|
|
6800
|
-
* @throws If the payload is neither valid compressed data nor valid JSON
|
|
6923
|
+
* @throws If the payload is neither valid compressed data nor valid JSON, or
|
|
6924
|
+
* declares a decompressed size above 64 MiB.
|
|
6801
6925
|
*/
|
|
6802
6926
|
export declare function decompressFromString<T>(raw: string): T;
|
|
6803
6927
|
|
|
@@ -6808,6 +6932,13 @@ export declare function decompressFromString<T>(raw: string): T;
|
|
|
6808
6932
|
* - Arrays and non-plain values (dates, class instances, primitives) replace
|
|
6809
6933
|
* the target value entirely — they are not merged element by element.
|
|
6810
6934
|
* - Neither `target` nor `source` is mutated.
|
|
6935
|
+
* - `__proto__`, `constructor` and `prototype` keys in `source` are skipped.
|
|
6936
|
+
* Assigning `result["__proto__"]` does not create a key: it **replaces the
|
|
6937
|
+
* result's prototype**, so a `JSON.parse`d settings blob carrying
|
|
6938
|
+
* `{"__proto__": {"isAdmin": true}}` produced an object whose `isAdmin` read
|
|
6939
|
+
* `true` through inheritance while `Object.keys` showed nothing. No global
|
|
6940
|
+
* prototype is touched either way; the skip removes the surprise, and the
|
|
6941
|
+
* other two names go with it because nothing legitimate merges into them.
|
|
6811
6942
|
*
|
|
6812
6943
|
* @example
|
|
6813
6944
|
* deepMerge(
|
|
@@ -8247,7 +8378,7 @@ export declare type FormActionsAlign = "start" | "center" | "end" | "between";
|
|
|
8247
8378
|
export declare interface FormActionsProps extends HTMLAttributes<HTMLDivElement> {
|
|
8248
8379
|
/** Horizontal alignment of buttons. Default `end`. */
|
|
8249
8380
|
align?: FormActionsAlign;
|
|
8250
|
-
/** Gap between buttons. Numbers map to a multiple of the 4px scale (default `2` → 8px). */
|
|
8381
|
+
/** Gap between buttons. Numbers map to a multiple of the 4px scale (default `2` → 8px). A number is a step, not pixels (`6` → 24px): above `12` a development build warns once, and a string such as `"96px"` passes through untouched. */
|
|
8251
8382
|
gap?: number | string;
|
|
8252
8383
|
}
|
|
8253
8384
|
|
|
@@ -8597,7 +8728,7 @@ export { FormProvider }
|
|
|
8597
8728
|
export declare function FormRow({ gap, className, style, children, ...props }: FormRowProps): JSX.Element;
|
|
8598
8729
|
|
|
8599
8730
|
export declare interface FormRowProps extends HTMLAttributes<HTMLDivElement> {
|
|
8600
|
-
/** Gap between row items. Numbers map to a multiple of the 4px scale (default `3` → 12px). */
|
|
8731
|
+
/** Gap between row items. Numbers map to a multiple of the 4px scale (default `3` → 12px). A number is a step, not pixels (`6` → 24px): above `12` a development build warns once, and a string such as `"96px"` passes through untouched. */
|
|
8601
8732
|
gap?: number | string;
|
|
8602
8733
|
}
|
|
8603
8734
|
|
|
@@ -8720,7 +8851,14 @@ export declare interface GetListParams {
|
|
|
8720
8851
|
field: string;
|
|
8721
8852
|
order?: "asc" | "desc";
|
|
8722
8853
|
};
|
|
8723
|
-
/**
|
|
8854
|
+
/**
|
|
8855
|
+
* Arbitrary filter query params, spread onto the request **before**
|
|
8856
|
+
* `pagination` and `sort`. A filter whose key equals a pagination or sort
|
|
8857
|
+
* param name (`page`, `size`, `order_by`, `ascending` by default) is
|
|
8858
|
+
* overridden by the structured value when that one is set: until 0.81.0 the
|
|
8859
|
+
* filter won, so `filters: { page: 1 }` from a table's filter state silently
|
|
8860
|
+
* pinned every request to page 1.
|
|
8861
|
+
*/
|
|
8724
8862
|
filters?: DataFilters;
|
|
8725
8863
|
}
|
|
8726
8864
|
|
|
@@ -8769,7 +8907,7 @@ export declare function getThemePreset(name: string): CreateThemeOptions | undef
|
|
|
8769
8907
|
* />
|
|
8770
8908
|
* </GoogleOAuthProvider>
|
|
8771
8909
|
*/
|
|
8772
|
-
export declare function GoogleSignIn({ component: Component, onSuccess, onError, locale, theme, text, shape, size, disableOneTap, width, className, style, }: GoogleSignInProps): JSX.Element;
|
|
8910
|
+
export declare function GoogleSignIn({ component: Component, onSuccess, onError, locale, theme, text, shape, size, disableOneTap, width, nonce, className, style, }: GoogleSignInProps): JSX.Element;
|
|
8773
8911
|
|
|
8774
8912
|
export declare interface GoogleSignInProps {
|
|
8775
8913
|
/**
|
|
@@ -8796,6 +8934,16 @@ export declare interface GoogleSignInProps {
|
|
|
8796
8934
|
disableOneTap?: boolean;
|
|
8797
8935
|
/** Optional `width` override (px) — Google's button is fixed-width. */
|
|
8798
8936
|
width?: number;
|
|
8937
|
+
/**
|
|
8938
|
+
* Server-issued nonce Google copies into the ID token's `nonce` claim.
|
|
8939
|
+
*
|
|
8940
|
+
* The backend issues one per sign-in attempt, keeps it, and rejects an
|
|
8941
|
+
* `id_token` whose claim does not match — which is what stops a token
|
|
8942
|
+
* captured elsewhere from being replayed against your API. Until 0.82.0
|
|
8943
|
+
* the wrapper dropped it, so an app could not bind the token through
|
|
8944
|
+
* `<GoogleSignIn>` at all (#530).
|
|
8945
|
+
*/
|
|
8946
|
+
nonce?: string;
|
|
8799
8947
|
/** Optional className applied to the wrapper. */
|
|
8800
8948
|
className?: string;
|
|
8801
8949
|
/** Optional inline style applied to the wrapper. */
|
|
@@ -8816,7 +8964,7 @@ export declare function Grid({ columns, gap, className, style, children, ...prop
|
|
|
8816
8964
|
export declare interface GridProps extends HTMLAttributes<HTMLDivElement> {
|
|
8817
8965
|
/** Number of columns or a custom `grid-template-columns` value. Accepts responsive object. */
|
|
8818
8966
|
columns?: ResponsiveValue<number | string>;
|
|
8819
|
-
/** Gap as a CSS length. Numbers map to a multiple of the 4px scale. Accepts responsive object. */
|
|
8967
|
+
/** Gap as a CSS length. Numbers map to a multiple of the 4px scale. Accepts responsive object. A number is a step, not pixels (`6` → 24px): above `12` a development build warns once, and a string such as `"96px"` passes through untouched. */
|
|
8820
8968
|
gap?: ResponsiveValue<number | string>;
|
|
8821
8969
|
children?: ReactNode;
|
|
8822
8970
|
}
|
|
@@ -9494,7 +9642,9 @@ export declare type InstallMethod = "native" | "ios" | "manual" | "none";
|
|
|
9494
9642
|
*
|
|
9495
9643
|
* A click on an action button opens that action's URL (see
|
|
9496
9644
|
* {@link PushNotificationAction.url}); a click on the body, or on an action
|
|
9497
|
-
* without one, opens the top-level `url`.
|
|
9645
|
+
* without one, opens the top-level `url`. Only a same-origin `http(s)` URL is
|
|
9646
|
+
* opened by default; see {@link InstallNotificationClickHandlerOptions.resolveUrl}
|
|
9647
|
+
* for opting into another origin.
|
|
9498
9648
|
*/
|
|
9499
9649
|
export declare function installNotificationClickHandler(options?: InstallNotificationClickHandlerOptions): void;
|
|
9500
9650
|
|
|
@@ -9503,6 +9653,12 @@ export declare interface InstallNotificationClickHandlerOptions {
|
|
|
9503
9653
|
* Resolve the destination URL from the notification data and the clicked
|
|
9504
9654
|
* action id (`""` or `undefined` for a click on the body). Default: the
|
|
9505
9655
|
* action's entry in `data.actionUrls`, else `data.url`, else `"/"`.
|
|
9656
|
+
*
|
|
9657
|
+
* The default only ever opens a page of the worker's **own origin**: a URL on
|
|
9658
|
+
* another origin, or with a scheme other than `http:`/`https:`, becomes `"/"`.
|
|
9659
|
+
* A resolver of your own is how an app opts into another origin — what it
|
|
9660
|
+
* returns may point anywhere `http:`/`https:`, and any other scheme still
|
|
9661
|
+
* becomes `"/"`.
|
|
9506
9662
|
*/
|
|
9507
9663
|
resolveUrl?: (data: unknown, action: string | undefined) => string;
|
|
9508
9664
|
}
|
|
@@ -9517,7 +9673,27 @@ export declare type InstallOutcome = "accepted" | "dismissed" | "unsupported";
|
|
|
9517
9673
|
* - on `fetch`, serves precached assets cache-first and falls back to the
|
|
9518
9674
|
* `navigateFallback` document for offline navigations (SPA routing).
|
|
9519
9675
|
*
|
|
9520
|
-
*
|
|
9676
|
+
* Survives the browser stopping and restarting the worker, which it does
|
|
9677
|
+
* whenever the worker sits idle and which never repeats `install`. Nothing the
|
|
9678
|
+
* fetch handler needs lives only in memory: `install` and `activate` record, in
|
|
9679
|
+
* an entry inside the versioned cache, when that version was installed and
|
|
9680
|
+
* activated, and a restarted worker reads back the activated version and its
|
|
9681
|
+
* pathnames from Cache Storage. Before 0.83.0 the cache name and the precached
|
|
9682
|
+
* paths were module variables filled only by `install`, so after the first
|
|
9683
|
+
* restart offline navigations failed with "offline and no cached app shell",
|
|
9684
|
+
* precached assets went to the network, and an `activate` in a run without
|
|
9685
|
+
* `install` deleted every precache, the current one included (#572).
|
|
9686
|
+
*
|
|
9687
|
+
* `activate` deletes the other `${cacheName}-*` caches only once it knows which
|
|
9688
|
+
* version it is activating; when no version recorded an install it deletes
|
|
9689
|
+
* nothing. In the first request after a restart, while the worker is still
|
|
9690
|
+
* reading which paths are precached, a same-origin `GET` that a runtime route
|
|
9691
|
+
* did not answer is answered with `fetch(request)` when it is not precached —
|
|
9692
|
+
* the decision to call `respondWith` cannot wait for Cache Storage. From then on
|
|
9693
|
+
* a non-precached request is left to the browser, as before.
|
|
9694
|
+
*
|
|
9695
|
+
* Same-origin only. Register this LAST, after any {@link installRuntimeCache}:
|
|
9696
|
+
* a request a runtime route answered is never answered again here.
|
|
9521
9697
|
*/
|
|
9522
9698
|
export declare function installPrecache(options?: InstallPrecacheOptions): void;
|
|
9523
9699
|
|
|
@@ -9549,8 +9725,9 @@ export declare interface InstallPrecacheOptions {
|
|
|
9549
9725
|
* Every `NotificationOptions` member the payload carries is forwarded —
|
|
9550
9726
|
* `actions`, `requireInteraction`, `vibrate`, `silent`, `renotify`,
|
|
9551
9727
|
* `timestamp`, `dir` and `lang` alongside `body`, `icon`, `badge`, `image` and
|
|
9552
|
-
* `tag`. `data` receives the top-level `url`
|
|
9553
|
-
*
|
|
9728
|
+
* `tag`. `data` receives the payload's own `data`, then the top-level `url`
|
|
9729
|
+
* (default `"/"`) and `actionUrls` mapping each action id to its `url` — in that
|
|
9730
|
+
* order, so `payload.data` cannot override where a click goes.
|
|
9554
9731
|
*/
|
|
9555
9732
|
export declare function installPushHandler(options?: InstallPushHandlerOptions): void;
|
|
9556
9733
|
|
|
@@ -9574,9 +9751,10 @@ export declare interface InstallPushHandlerOptions {
|
|
|
9574
9751
|
* `respondWith`), so a later {@link installPrecache} can handle them.
|
|
9575
9752
|
*
|
|
9576
9753
|
* A request carrying a credential header (`Authorization`, `X-Api-Key`, … — the
|
|
9577
|
-
* route's `credentialHeaders`)
|
|
9754
|
+
* route's `credentialHeaders`), or a CORS `fetch` sent with
|
|
9755
|
+
* `credentials: "include"`, is also left untouched unless its route sets
|
|
9578
9756
|
* `cacheAuthenticated`, and a response with `Cache-Control: no-store`
|
|
9579
|
-
* (or `private`, without that opt-in) is served but never stored. `maxAgeSeconds`
|
|
9757
|
+
* (or `private`, without that opt-in) or `Vary: *` is served but never stored. `maxAgeSeconds`
|
|
9580
9758
|
* applies to every read, including the offline fallback: an expired entry is a
|
|
9581
9759
|
* miss, never a last resort. Under `rangeRequests`, the full resource is cached
|
|
9582
9760
|
* once (the `Range` header stripped) and each range is sliced from it.
|
|
@@ -9973,11 +10151,13 @@ declare type IssuePathSegment = PropertyKey | {
|
|
|
9973
10151
|
* rather than the request blocked: the upload still goes through, it just goes
|
|
9974
10152
|
* without the API's bearer token.
|
|
9975
10153
|
*
|
|
9976
|
-
* Both sides are resolved
|
|
9977
|
-
*
|
|
9978
|
-
*
|
|
9979
|
-
*
|
|
9980
|
-
*
|
|
10154
|
+
* Both sides are resolved first, so a relative `baseURL` or `endpoint` — the
|
|
10155
|
+
* shape behind a dev-server or reverse proxy — compares equal to the absolute
|
|
10156
|
+
* URL the request actually goes to. The target resolves against the document
|
|
10157
|
+
* base URL, where the transport sends it; the reference against the page's
|
|
10158
|
+
* own address, which a `<base href>` cannot move. Outside a browsing context a
|
|
10159
|
+
* relative target is allowed — there is no origin for it to cross — and a
|
|
10160
|
+
* target that does not parse is refused rather than trusted.
|
|
9981
10161
|
*
|
|
9982
10162
|
* @param target - The URL the request is about to go to.
|
|
9983
10163
|
* @param reference - The origin the credential belongs to, normally the
|
|
@@ -10273,7 +10453,7 @@ declare interface LayoutProps {
|
|
|
10273
10453
|
layout?: FormLayout;
|
|
10274
10454
|
/** Number of columns when `layout="grid"`, or a custom `grid-template-columns` value. Default `2`. */
|
|
10275
10455
|
columns?: number | string;
|
|
10276
|
-
/** Gap between fields. Numbers map to a multiple of the 4px scale (default `4` → 16px). */
|
|
10456
|
+
/** Gap between fields. Numbers map to a multiple of the 4px scale (default `4` → 16px). A number is a step, not pixels (`6` → 24px): above `12` a development build warns once, and a string such as `"96px"` passes through untouched. */
|
|
10277
10457
|
gap?: number | string;
|
|
10278
10458
|
}
|
|
10279
10459
|
|
|
@@ -11604,7 +11784,12 @@ export declare function NavigationMenu({ items, portal, className, ...props }: N
|
|
|
11604
11784
|
export declare interface NavigationMenuItem {
|
|
11605
11785
|
/** Visible label for the entry. */
|
|
11606
11786
|
label: ReactNode;
|
|
11607
|
-
/**
|
|
11787
|
+
/**
|
|
11788
|
+
* When set, the entry renders as an anchor. The URL is checked against
|
|
11789
|
+
* `safeLinkUrl`'s allowlist: a scheme outside `http:`/`https:`/`mailto:`/`tel:`/`sms:`
|
|
11790
|
+
* renders the entry as a button instead, so a menu built from API data cannot
|
|
11791
|
+
* put a clickable `javascript:` link on the page under React 18.
|
|
11792
|
+
*/
|
|
11608
11793
|
href?: string;
|
|
11609
11794
|
/** Invoked when the entry is activated (click / Enter). */
|
|
11610
11795
|
onSelect?: () => void;
|
|
@@ -11976,7 +12161,8 @@ export declare interface OfflineQueryPersistence {
|
|
|
11976
12161
|
/**
|
|
11977
12162
|
* Load the persisted snapshot into the `QueryClient`. Call once on boot,
|
|
11978
12163
|
* before rendering queries, so cached data is available offline. A no-op
|
|
11979
|
-
* once {@link OfflineQueryPersistence.clear} has been called
|
|
12164
|
+
* once {@link OfflineQueryPersistence.clear} has been called, and — with
|
|
12165
|
+
* `getPrincipal` — for a snapshot written under another principal.
|
|
11980
12166
|
*/
|
|
11981
12167
|
restore: () => Promise<void>;
|
|
11982
12168
|
/**
|
|
@@ -12036,6 +12222,39 @@ export declare interface OfflineQueryPersistenceOptions {
|
|
|
12036
12222
|
* one trailing write per window. Default `1000`.
|
|
12037
12223
|
*/
|
|
12038
12224
|
throttleMs?: number;
|
|
12225
|
+
/**
|
|
12226
|
+
* Who is signed in right now — a stable, non-secret id such as the user id;
|
|
12227
|
+
* `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
|
|
12229
|
+
* `restore()`, which hydrates only a snapshot stamped with the same
|
|
12230
|
+
* fingerprint.
|
|
12231
|
+
*
|
|
12232
|
+
* `clear()` on logout already deletes the snapshot; this covers the session
|
|
12233
|
+
* that ends without it — a token that expired, a crash, a tab closed while
|
|
12234
|
+
* signed in. Without it, the next account to boot on the browser is shown
|
|
12235
|
+
* the previous account's cached responses (#531). A snapshot written before
|
|
12236
|
+
* this option was set carries no stamp and is not restored either; it is a
|
|
12237
|
+
* cache, so the cost is one cold start.
|
|
12238
|
+
*
|
|
12239
|
+
* A foreign snapshot is skipped, not deleted: a cookie app that only learns
|
|
12240
|
+
* the principal after a `/me` round trip would otherwise wipe its own cache
|
|
12241
|
+
* on every cold start. The next write replaces it.
|
|
12242
|
+
*
|
|
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
|
|
12248
|
+
* before anyone signs in stay anonymous and are restored while nobody is,
|
|
12249
|
+
* so an app that persists logged-out data keeps doing so. An anonymous
|
|
12250
|
+
* snapshot written by 0.82.0 is not restored (it may hold an expired
|
|
12251
|
+
* session's cache): one cold start, once.
|
|
12252
|
+
*
|
|
12253
|
+
* Read synchronously. A non-string, non-number value (the `Promise` of an
|
|
12254
|
+
* `async` getter) or a getter that throws reads as nobody. Omit it to restore
|
|
12255
|
+
* every snapshot, as before 0.82.0.
|
|
12256
|
+
*/
|
|
12257
|
+
getPrincipal?: () => string | number | null | undefined;
|
|
12039
12258
|
}
|
|
12040
12259
|
|
|
12041
12260
|
/** Maps each table name to the record type it stores. */
|
|
@@ -12212,6 +12431,30 @@ export declare interface OfflineSyncConfig<TPayload, TRemote> {
|
|
|
12212
12431
|
crossTab?: boolean;
|
|
12213
12432
|
/** Channel name when `crossTab` is on. Default `tempest-sync:${databaseName}`. */
|
|
12214
12433
|
broadcastChannelName?: string;
|
|
12434
|
+
/**
|
|
12435
|
+
* Who is signed in right now — a stable, non-secret id such as the user id;
|
|
12436
|
+
* `null`/`undefined` when nobody is. Read synchronously when an entry is
|
|
12437
|
+
* queued, which stamps it with a one-way fingerprint (`entry.owner`, never
|
|
12438
|
+
* the id itself), and again right before each delivery:
|
|
12439
|
+
*
|
|
12440
|
+
* - same principal → delivered;
|
|
12441
|
+
* - nobody signed in now → held: it stays queued and goes out when its owner
|
|
12442
|
+
* signs back in, so a flush fired by the `online` event before login loses
|
|
12443
|
+
* nothing;
|
|
12444
|
+
* - anybody else → deleted unsent and counted in `summary.dropped`, because
|
|
12445
|
+
* delivering it would send the previous account's mutation with the next
|
|
12446
|
+
* account's session.
|
|
12447
|
+
*
|
|
12448
|
+
* `clearOutbox()` on logout already empties the queue; this covers the app
|
|
12449
|
+
* that forgets it, or a session that ends without a logout (#531). Entries
|
|
12450
|
+
* queued before this option was set carry no stamp and are delivered as
|
|
12451
|
+
* before — they are the user's own unsynced edits, and holding them would
|
|
12452
|
+
* strand every queue on upgrade.
|
|
12453
|
+
*
|
|
12454
|
+
* A non-string, non-number value (the `Promise` of an `async` getter) or a
|
|
12455
|
+
* getter that throws reads as nobody. Default: no owner binding.
|
|
12456
|
+
*/
|
|
12457
|
+
getPrincipal?: () => string | number | null | undefined;
|
|
12215
12458
|
}
|
|
12216
12459
|
|
|
12217
12460
|
export declare interface OfflineTableConfig<TItem> {
|
|
@@ -12493,6 +12736,13 @@ export declare interface OutboxEntry<TPayload = unknown> {
|
|
|
12493
12736
|
lastError?: string;
|
|
12494
12737
|
/** Record snapshot for `create`/`update`. Omitted for `delete`. */
|
|
12495
12738
|
payload?: TPayload;
|
|
12739
|
+
/**
|
|
12740
|
+
* One-way fingerprint of whoever was signed in when the entry was queued
|
|
12741
|
+
* (`null` for nobody), stamped only when the engine has
|
|
12742
|
+
* {@link OfflineSyncConfig.getPrincipal}. Absent on entries queued without
|
|
12743
|
+
* it, which are delivered as before.
|
|
12744
|
+
*/
|
|
12745
|
+
owner?: string | null;
|
|
12496
12746
|
}
|
|
12497
12747
|
|
|
12498
12748
|
/**
|
|
@@ -13059,6 +13309,23 @@ export declare interface PeerMeshOptions {
|
|
|
13059
13309
|
onState?: (state: MeshState, detail?: string) => void;
|
|
13060
13310
|
/** Called for a failure worth surfacing that is not fatal to the mesh. */
|
|
13061
13311
|
onNotice?: (reason: string) => void;
|
|
13312
|
+
/**
|
|
13313
|
+
* Decide whether an offer from a peer the mesh has no link to is answered.
|
|
13314
|
+
*
|
|
13315
|
+
* By default the mesh answers any offer that reaches {@link PeerMesh.accept},
|
|
13316
|
+
* opening a link and publishing the local tracks to it — the answering side
|
|
13317
|
+
* usually learns of a peer from its offer, so that is the documented flow.
|
|
13318
|
+
* It also means whether the microphone and camera reach someone rests only
|
|
13319
|
+
* on the signalling server relaying offers to the right people. Pass a gate
|
|
13320
|
+
* — typically "is this user in the room roster I fetched" — to make that
|
|
13321
|
+
* the app's decision too. A refused offer opens nothing, answers nothing and
|
|
13322
|
+
* reports `onNotice("offer_refused")`. Peers added with `addPeer` are not
|
|
13323
|
+
* asked: adding them was the decision.
|
|
13324
|
+
*
|
|
13325
|
+
* @param peerId - The `from` of the offer.
|
|
13326
|
+
* @returns `true` to answer it.
|
|
13327
|
+
*/
|
|
13328
|
+
acceptPeer?: (peerId: string) => boolean;
|
|
13062
13329
|
/** Initial encoder limits. */
|
|
13063
13330
|
quality?: MeshQuality;
|
|
13064
13331
|
/** Measure every link, on one timer the mesh owns. See {@link MeshStatsOptions}. */
|
|
@@ -13541,7 +13808,13 @@ export declare function projectMercator(coord: Coordinate): MercatorPoint;
|
|
|
13541
13808
|
*
|
|
13542
13809
|
* Pass `getPrincipal` to bind each entry to whoever queued it: the worker asks
|
|
13543
13810
|
* the issuing tab right after queueing, asks every tab again before replaying,
|
|
13544
|
-
* and drops the entry when no signed-in tab is its owner.
|
|
13811
|
+
* and drops the entry when no signed-in tab is its owner. Without it every
|
|
13812
|
+
* entry is `"unbound"` and replays with whichever session answers — the next
|
|
13813
|
+
* account's bearer included, unless `clearSessionData()` ran on logout — so a
|
|
13814
|
+
* development build warns once per call (#531). Treating an unbound
|
|
13815
|
+
* credentialed entry as `"unknown"` instead would change nothing: an
|
|
13816
|
+
* `"unknown"` entry replays when no answering tab reports a principal, which is
|
|
13817
|
+
* exactly the page that omits `getPrincipal`.
|
|
13545
13818
|
*
|
|
13546
13819
|
* @param getHeaders - Resolves the headers for one queued request at replay.
|
|
13547
13820
|
* @param options - `getPrincipal` binds entries to their owner.
|
|
@@ -13663,7 +13936,14 @@ export declare interface PushPayload {
|
|
|
13663
13936
|
dir?: NotificationDirection;
|
|
13664
13937
|
/** BCP 47 language tag of the title and body. */
|
|
13665
13938
|
lang?: string;
|
|
13666
|
-
/**
|
|
13939
|
+
/**
|
|
13940
|
+
* Arbitrary extra data forwarded to `event.notification.data`.
|
|
13941
|
+
*
|
|
13942
|
+
* Its `url` and `actionUrls` keys are overwritten by the top-level `url` and
|
|
13943
|
+
* the actions' `url`s: those two keys decide where a click goes, and a
|
|
13944
|
+
* free-form bag — often filled from the record that triggered the push — must
|
|
13945
|
+
* not be able to redirect it.
|
|
13946
|
+
*/
|
|
13667
13947
|
data?: Record<string, unknown>;
|
|
13668
13948
|
}
|
|
13669
13949
|
|
|
@@ -14554,6 +14834,13 @@ export declare interface ResumableUpload {
|
|
|
14554
14834
|
/**
|
|
14555
14835
|
* Stop for good.
|
|
14556
14836
|
*
|
|
14837
|
+
* A later `start()`/`resume()` on the same handle attaches as a new handle
|
|
14838
|
+
* would (since 0.83.0): it resumes the stored record only when the current
|
|
14839
|
+
* owner stamped it, and otherwise creates a new upload with a fresh
|
|
14840
|
+
* `Idempotency-Key`. Until then a token-bound handle resumed its own upload
|
|
14841
|
+
* with whatever token was current — after an account switch, the next
|
|
14842
|
+
* account's (#561).
|
|
14843
|
+
*
|
|
14557
14844
|
* @param options - `discard: true` also sends `DELETE` (tus termination) and
|
|
14558
14845
|
* forgets the persisted record, so the next `start()` uploads from zero.
|
|
14559
14846
|
*/
|
|
@@ -14580,7 +14867,21 @@ export declare interface ResumableUploadOptions {
|
|
|
14580
14867
|
chunkSize?: number;
|
|
14581
14868
|
/** Sent as `Upload-Metadata` (base64-encoded values), e.g. `{ filename }`. */
|
|
14582
14869
|
metadata?: Record<string, string>;
|
|
14583
|
-
/**
|
|
14870
|
+
/**
|
|
14871
|
+
* Extra headers on every request inside the credential scope — the
|
|
14872
|
+
* `endpoint`'s origin plus {@link trustedOrigins}. A `Location` on another
|
|
14873
|
+
* host gets only the tus headers, never these (since 0.82.0).
|
|
14874
|
+
*
|
|
14875
|
+
* A request that carries them never follows a redirect (since 0.83.0): it
|
|
14876
|
+
* goes out over `fetch` with `redirect: "manual"`, and a redirect rejects
|
|
14877
|
+
* with a `TempestApiError` of `code: "REDIRECT_REFUSED"`. An
|
|
14878
|
+
* `XMLHttpRequest` follows every redirect, and these headers went with it
|
|
14879
|
+
* to the other origin (#564). The cost: `fetch` reports no upload
|
|
14880
|
+
* progress, so `onProgress` then ticks once per confirmed chunk — lower
|
|
14881
|
+
* `chunkSize` for a finer bar, or send the credential through `getToken`,
|
|
14882
|
+
* which keeps the `XMLHttpRequest` (the browser strips `Authorization` on
|
|
14883
|
+
* a cross-origin redirect).
|
|
14884
|
+
*/
|
|
14584
14885
|
headers?: Record<string, string>;
|
|
14585
14886
|
/** Returns the current bearer token, read before each request. */
|
|
14586
14887
|
getToken?: () => string | null | undefined;
|
|
@@ -14592,13 +14893,20 @@ export declare interface ResumableUploadOptions {
|
|
|
14592
14893
|
* The resume record is stamped with a one-way fingerprint of it, and a
|
|
14593
14894
|
* record stamped by anyone else — another user, nobody, or no stamp at all
|
|
14594
14895
|
* — is deleted instead of resumed: its upload URL is not probed, and its
|
|
14595
|
-
* `Idempotency-Key` is never replayed.
|
|
14596
|
-
*
|
|
14597
|
-
*
|
|
14598
|
-
*
|
|
14599
|
-
*
|
|
14600
|
-
*
|
|
14601
|
-
*
|
|
14896
|
+
* `Idempotency-Key` is never replayed (#479).
|
|
14897
|
+
*
|
|
14898
|
+
* Without it, since 0.82.0 the record is bound to a fingerprint of the
|
|
14899
|
+
* `getToken` token instead, so another account's record is still never
|
|
14900
|
+
* adopted (#528) — but a token rotates: a reload after a refresh that no
|
|
14901
|
+
* chunk landed under starts the upload over. Pass `getPrincipal` to keep
|
|
14902
|
+
* resuming across refreshes, and always with a cookie session, where there
|
|
14903
|
+
* is no token to bind to and the record stays unbound.
|
|
14904
|
+
*
|
|
14905
|
+
* `getToken: auth.getToken` — the getter of `createTempestAuth` itself, not
|
|
14906
|
+
* an arrow around it — binds to that preset's session instead, as if
|
|
14907
|
+
* `getPrincipal: auth.sessionKey` were passed: the record survives token
|
|
14908
|
+
* rotation, a switch of account stops the run, and a new `login()`, even
|
|
14909
|
+
* into the same account, starts over.
|
|
14602
14910
|
*
|
|
14603
14911
|
* It is read again before every chunk and every record write: when it
|
|
14604
14912
|
* names someone else mid-run, the run stops with
|
|
@@ -14675,10 +14983,11 @@ export declare interface ResumableUploadRecord {
|
|
|
14675
14983
|
/** Epoch ms of the last write, so an app can sweep stale records. */
|
|
14676
14984
|
updatedAt: number;
|
|
14677
14985
|
/**
|
|
14678
|
-
* One-way fingerprint of the principal that created the upload (`"p:<hex>"`)
|
|
14679
|
-
*
|
|
14680
|
-
*
|
|
14681
|
-
*
|
|
14986
|
+
* One-way fingerprint of the principal that created the upload (`"p:<hex>"`)
|
|
14987
|
+
* or, without {@link ResumableUploadOptions.getPrincipal}, of the bearer
|
|
14988
|
+
* token of its last write (`"t:<hex>"`, since 0.82.0); `null` for an
|
|
14989
|
+
* anonymous one. Absent when the upload ran with neither getter, and on
|
|
14990
|
+
* records written before 0.78.0.
|
|
14682
14991
|
*/
|
|
14683
14992
|
owner?: string | null;
|
|
14684
14993
|
}
|
|
@@ -14999,8 +15308,9 @@ export declare interface RuntimeRoute {
|
|
|
14999
15308
|
*/
|
|
15000
15309
|
rangeRequests?: boolean;
|
|
15001
15310
|
/**
|
|
15002
|
-
* Opt in to caching requests that carry a credential
|
|
15003
|
-
* `credentialHeaders`)
|
|
15311
|
+
* Opt in to caching credentialed requests — those that carry a credential
|
|
15312
|
+
* header (see `credentialHeaders`) or are a CORS-mode `fetch` sent with
|
|
15313
|
+
* `credentials: "include"` — and responses marked `Cache-Control: private`.
|
|
15004
15314
|
* Default `false`.
|
|
15005
15315
|
*
|
|
15006
15316
|
* Cache Storage is keyed by URL and outlives the session: without this
|
|
@@ -15017,11 +15327,18 @@ export declare interface RuntimeRoute {
|
|
|
15017
15327
|
* `clearSessionData()` on logout, which removes the entries themselves.
|
|
15018
15328
|
* `Cache-Control: no-store` is never cached, opt-in or not.
|
|
15019
15329
|
*
|
|
15020
|
-
* A cookie session is
|
|
15021
|
-
*
|
|
15022
|
-
*
|
|
15330
|
+
* A cookie session is only partly visible here: the worker cannot see
|
|
15331
|
+
* `Cookie`. What it can see is a `fetch` that asked for cookies explicitly —
|
|
15332
|
+
* `mode: "cors"` with `credentials: "include"`, which is what `ApiClient`
|
|
15333
|
+
* sends under `withCredentials` — and since 0.82.0 that request is treated
|
|
15334
|
+
* as credentialed too (#531). `<img>`, `<audio>` and `<video>` also send
|
|
15335
|
+
* `credentials: "include"`, but in `no-cors` mode, so they keep caching. A
|
|
15336
|
+
* plain same-origin `fetch` (`credentials: "same-origin"`, the default)
|
|
15337
|
+
* carries the cookie without saying so; such an API stays private only
|
|
15023
15338
|
* through `Cache-Control: private`/`no-store` on its responses and
|
|
15024
|
-
* `clearSessionData()` on logout.
|
|
15339
|
+
* `clearSessionData()` on logout. Opting a cookie request in caches it by
|
|
15340
|
+
* URL — there is no credential header to vary on — so `clearSessionData()`
|
|
15341
|
+
* is then its only isolation.
|
|
15025
15342
|
*/
|
|
15026
15343
|
cacheAuthenticated?: boolean;
|
|
15027
15344
|
/**
|
|
@@ -15645,6 +15962,16 @@ export declare interface SequentialScaleOptions {
|
|
|
15645
15962
|
ordinal?: boolean;
|
|
15646
15963
|
}
|
|
15647
15964
|
|
|
15965
|
+
/**
|
|
15966
|
+
* Identifies the session a stream belongs to: the signed-in user's id, an
|
|
15967
|
+
* auth epoch, `null` when signed out.
|
|
15968
|
+
*
|
|
15969
|
+
* A primitive on purpose. The hook form lists it in its effect dependencies,
|
|
15970
|
+
* and an object built inline would be a new identity on every render, so the
|
|
15971
|
+
* stream would reopen on every render.
|
|
15972
|
+
*/
|
|
15973
|
+
export declare type SessionKey = string | number | boolean | null | undefined;
|
|
15974
|
+
|
|
15648
15975
|
/**
|
|
15649
15976
|
* Thrown when the session that started an operation is no longer the current
|
|
15650
15977
|
* one by the time it settles: a `refresh` hook (rethrown by
|
|
@@ -16026,6 +16353,10 @@ export declare interface SidebarItem {
|
|
|
16026
16353
|
* A `disabled` entry ignores this and stays a `<button disabled>`: there is no
|
|
16027
16354
|
* disabled state for an anchor, and dropping the `href` to fake one leaves a
|
|
16028
16355
|
* link that announces itself as actionable and is not.
|
|
16356
|
+
*
|
|
16357
|
+
* The URL goes through `safeLinkUrl`: a scheme outside
|
|
16358
|
+
* `http:`/`https:`/`mailto:`/`tel:`/`sms:` makes the entry a button, the same
|
|
16359
|
+
* as an entry without `href`.
|
|
16029
16360
|
*/
|
|
16030
16361
|
href?: string;
|
|
16031
16362
|
}
|
|
@@ -16506,7 +16837,7 @@ export declare type StackJustify = "start" | "center" | "end" | "between";
|
|
|
16506
16837
|
export declare interface StackProps extends HTMLAttributes<HTMLDivElement> {
|
|
16507
16838
|
/** Direction. Accepts responsive object — e.g. `{ mobile: "vertical", desktop: "horizontal" }`. */
|
|
16508
16839
|
direction?: ResponsiveValue<StackDirection>;
|
|
16509
|
-
/** Gap as a CSS length. Numbers map to a multiple of the 4px scale. Accepts responsive object. */
|
|
16840
|
+
/** Gap as a CSS length. Numbers map to a multiple of the 4px scale. Accepts responsive object. A number is a step, not pixels (`6` → 24px): above `12` a development build warns once, and a string such as `"96px"` passes through untouched. */
|
|
16510
16841
|
gap?: ResponsiveValue<number | string>;
|
|
16511
16842
|
align?: StackAlign;
|
|
16512
16843
|
justify?: StackJustify;
|
|
@@ -16727,6 +17058,17 @@ export declare interface SyncRunSummary {
|
|
|
16727
17058
|
* run that went to completion.
|
|
16728
17059
|
*/
|
|
16729
17060
|
interrupted?: true;
|
|
17061
|
+
/**
|
|
17062
|
+
* Entries left queued because nobody is signed in and they belong to
|
|
17063
|
+
* somebody (see {@link OfflineSyncConfig.getPrincipal}). Absent when zero.
|
|
17064
|
+
*/
|
|
17065
|
+
held?: number;
|
|
17066
|
+
/**
|
|
17067
|
+
* Entries deleted unsent because they were queued under another principal —
|
|
17068
|
+
* or while signed out — and somebody else is signed in now (see
|
|
17069
|
+
* {@link OfflineSyncConfig.getPrincipal}). Absent when zero.
|
|
17070
|
+
*/
|
|
17071
|
+
dropped?: number;
|
|
16730
17072
|
}
|
|
16731
17073
|
|
|
16732
17074
|
/**
|
|
@@ -17020,6 +17362,28 @@ export declare interface TempestAuth<TUser, TCredentials> {
|
|
|
17020
17362
|
refresh: () => Promise<void>;
|
|
17021
17363
|
/** The current access token, or null. */
|
|
17022
17364
|
getToken: () => string | null;
|
|
17365
|
+
/**
|
|
17366
|
+
* The key of the session signed in now, or `null` when nobody is.
|
|
17367
|
+
*
|
|
17368
|
+
* It changes when the session is replaced — `login()`, even into the same
|
|
17369
|
+
* account, a sign-in or sign-out in another tab, `logout()` — and stays
|
|
17370
|
+
* the same while that session's tokens rotate: it is the session lineage
|
|
17371
|
+
* `login()` mints, not the token. That is the identity a per-session
|
|
17372
|
+
* resource needs. `useTicketEventStream`/`createTicketEventStream` read it
|
|
17373
|
+
* on their own from `api`, and `createResumableUpload` from `getToken`;
|
|
17374
|
+
* pass it as `sessionKey` or `getPrincipal` anywhere else.
|
|
17375
|
+
*
|
|
17376
|
+
* A session restored by `refresh()` with none installed — the boot
|
|
17377
|
+
* restore from a refresh cookie, an OAuth callback — is a new sign-in and
|
|
17378
|
+
* gets a lineage of its own, like `login()` (#561). A session persisted
|
|
17379
|
+
* before lineages existed has none in storage; its key is minted by this
|
|
17380
|
+
* preset for as long as that session lasts, so it survives the session's
|
|
17381
|
+
* rotations but no other session ever shares it. Until 0.82.0 both cases
|
|
17382
|
+
* answered one constant for every account, and an upload bound by
|
|
17383
|
+
* `getToken: auth.getToken` was resumed by the next account restored the
|
|
17384
|
+
* same way.
|
|
17385
|
+
*/
|
|
17386
|
+
sessionKey: () => string | null;
|
|
17023
17387
|
/**
|
|
17024
17388
|
* Stop following the other tabs: removes the `storage` listener this
|
|
17025
17389
|
* preset adds to `window`. Idempotent.
|
|
@@ -17194,6 +17558,10 @@ export declare function themeContrast(options: CreateThemeOptions): number | nul
|
|
|
17194
17558
|
* hydrates. Inline this in `<head>` to avoid a flash of the wrong theme on
|
|
17195
17559
|
* first paint.
|
|
17196
17560
|
*
|
|
17561
|
+
* Both options are embedded through an escaper that keeps them inside the
|
|
17562
|
+
* `<script>` element whatever they contain, so the snippet is safe to inline
|
|
17563
|
+
* even when the storage key comes from configuration.
|
|
17564
|
+
*
|
|
17197
17565
|
* @example
|
|
17198
17566
|
* <script dangerouslySetInnerHTML={{ __html: themeInitScript() }} />
|
|
17199
17567
|
*/
|
|
@@ -17289,6 +17657,10 @@ export declare interface TicketEventStreamSource {
|
|
|
17289
17657
|
* Authenticated client the ticket is requested through, so it carries the
|
|
17290
17658
|
* `Authorization` header or the session cookie, the CSRF header, and the
|
|
17291
17659
|
* 401 refresh-and-replay that a hand-rolled `fetch` would lose.
|
|
17660
|
+
*
|
|
17661
|
+
* The `api` of `createTempestAuth` also carries the session it acts for,
|
|
17662
|
+
* and the stream binds to it when `sessionKey` is not passed — see
|
|
17663
|
+
* {@link useTicketEventStream}.
|
|
17292
17664
|
*/
|
|
17293
17665
|
client: Pick<ApiClient, "post" | "url">;
|
|
17294
17666
|
/** Router prefix, relative to the client's base URL. Default: `"/sse"`. */
|
|
@@ -18094,7 +18466,12 @@ export declare function uploadFingerprint(endpoint: string, file: Blob | File):
|
|
|
18094
18466
|
* allowing a preflight.
|
|
18095
18467
|
*
|
|
18096
18468
|
* A file larger than `post.max_bytes` is refused before anything is sent, with
|
|
18097
|
-
* the same `413 FILE_TOO_LARGE` the server would answer.
|
|
18469
|
+
* the same `413 FILE_TOO_LARGE` the server would answer. A numeric string
|
|
18470
|
+
* (`"5242880"`) compares as a number; a missing or non-numeric `max_bytes` —
|
|
18471
|
+
* a bare boto3 `generate_presigned_post` has none — skips this precheck, and
|
|
18472
|
+
* the signed policy's `content-length-range` stays the control that refuses
|
|
18473
|
+
* the bytes. The precheck saves a wasted upload; it never was the limit.
|
|
18474
|
+
* Server errors are
|
|
18098
18475
|
* normalized into one `TempestApiError` whichever backend answered: the S3 XML
|
|
18099
18476
|
* (`EntityTooLarge` → `FILE_TOO_LARGE`, `EntityTooSmall` → `FILE_TOO_SMALL`,
|
|
18100
18477
|
* `AccessDenied` → `SIGNED_URL_INVALID`, or `SIGNED_URL_EXPIRED` when the policy
|
|
@@ -18138,6 +18515,11 @@ export declare interface UploadProgressEvent {
|
|
|
18138
18515
|
* back to `XMLHttpRequest`. It mirrors the error contract used by
|
|
18139
18516
|
* {@link createApiClient}: non-2xx responses reject with a `TempestApiError`.
|
|
18140
18517
|
*
|
|
18518
|
+
* An `XMLHttpRequest` cannot refuse a redirect; see
|
|
18519
|
+
* {@link UploadWithProgressOptions.redirect} for what follows one, what the
|
|
18520
|
+
* helper still refuses, and the `fetch` path that trades progress for never
|
|
18521
|
+
* following.
|
|
18522
|
+
*
|
|
18141
18523
|
* @returns The parsed JSON response, or the raw text when the response is not JSON.
|
|
18142
18524
|
*/
|
|
18143
18525
|
export declare function uploadWithProgress<T = unknown>(options: UploadWithProgressOptions): Promise<T>;
|
|
@@ -18151,18 +18533,22 @@ export declare interface UploadWithProgressOptions {
|
|
|
18151
18533
|
getToken?: () => string | null | undefined;
|
|
18152
18534
|
/**
|
|
18153
18535
|
* Origin the `getToken` credential belongs to, normally the API's.
|
|
18536
|
+
* Defaults to the page's own origin (`location.origin`).
|
|
18154
18537
|
*
|
|
18155
18538
|
* Unlike `createApiClient`, this helper has no base URL to infer a scope
|
|
18156
|
-
* from — the caller names the destination on every call
|
|
18157
|
-
*
|
|
18158
|
-
*
|
|
18159
|
-
*
|
|
18160
|
-
*
|
|
18539
|
+
* from — the caller names the destination on every call, and the `url` can
|
|
18540
|
+
* come from somewhere other than your own code (a signed URL the API handed
|
|
18541
|
+
* back, a value from a response body). Until 0.82.0 an unset scope sent the
|
|
18542
|
+
* token wherever `url` pointed; it now starts closed, like the CSRF token
|
|
18543
|
+
* always did, and an API on another origin sets this to receive it (#530).
|
|
18544
|
+
*
|
|
18545
|
+
* Outside a browsing context there is no page origin, and the scope falls
|
|
18546
|
+
* back to `url` itself.
|
|
18161
18547
|
*/
|
|
18162
18548
|
credentialOrigin?: string;
|
|
18163
18549
|
/**
|
|
18164
18550
|
* Extra origins allowed to receive the credential, on top of
|
|
18165
|
-
* {@link credentialOrigin}
|
|
18551
|
+
* {@link credentialOrigin} (or the page origin it defaults to).
|
|
18166
18552
|
*/
|
|
18167
18553
|
trustedOrigins?: readonly string[];
|
|
18168
18554
|
/** Send cookies. Defaults to false. */
|
|
@@ -18171,12 +18557,9 @@ export declare interface UploadWithProgressOptions {
|
|
|
18171
18557
|
* Send a CSRF token with the upload, as `createApiClient`'s `csrf` does.
|
|
18172
18558
|
* Off by default; `true` reads the `csrf_token` cookie into `X-CSRF-Token`.
|
|
18173
18559
|
*
|
|
18174
|
-
* Scoped
|
|
18175
|
-
*
|
|
18176
|
-
*
|
|
18177
|
-
* only for compatibility with every version before 0.66.0; this option is
|
|
18178
|
-
* new, so it starts closed. An API on another origin sets
|
|
18179
|
-
* `credentialOrigin` to receive the token.
|
|
18560
|
+
* Scoped exactly like the bearer token: to {@link credentialOrigin} (the
|
|
18561
|
+
* page's own origin when unset) plus {@link trustedOrigins}. An API on
|
|
18562
|
+
* another origin sets `credentialOrigin` to receive the token.
|
|
18180
18563
|
*/
|
|
18181
18564
|
csrf?: boolean | CsrfOptions;
|
|
18182
18565
|
/** Called on every `progress` event from the XHR upload channel. */
|
|
@@ -18190,6 +18573,33 @@ export declare interface UploadWithProgressOptions {
|
|
|
18190
18573
|
* Defaults to a generated id. Return an empty string to disable.
|
|
18191
18574
|
*/
|
|
18192
18575
|
requestId?: () => string;
|
|
18576
|
+
/**
|
|
18577
|
+
* What to do when the server answers with a redirect. Default `"follow"`.
|
|
18578
|
+
*
|
|
18579
|
+
* - `"follow"` — the `XMLHttpRequest` path, with byte-level progress. The
|
|
18580
|
+
* 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
|
|
18587
|
+
* `code: "REDIRECT_REFUSED"`, so that host cannot hand the app a URL to
|
|
18588
|
+
* store. Until 0.82.0 it resolved with the other host's body.
|
|
18589
|
+
* - `"error"` — goes out over `fetch` with `redirect: "manual"`, and a
|
|
18590
|
+
* redirect rejects with `code: "REDIRECT_REFUSED"` before anything is
|
|
18591
|
+
* 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
|
|
18593
|
+
* streamed `fetch` body would report progress, but Chrome refuses one
|
|
18594
|
+
* over HTTP/1.1 (`TypeError: Failed to fetch`, measured) and Firefox and
|
|
18595
|
+
* Safari do not support it.
|
|
18596
|
+
*
|
|
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.
|
|
18601
|
+
*/
|
|
18602
|
+
redirect?: "follow" | "error";
|
|
18193
18603
|
}
|
|
18194
18604
|
|
|
18195
18605
|
/**
|
|
@@ -18557,9 +18967,19 @@ export declare function useBreakpoint(): BreakpointHelpers;
|
|
|
18557
18967
|
*
|
|
18558
18968
|
* Handles sync booleans, sync {@link CanResult}, and promises of either. When
|
|
18559
18969
|
* no provider is present, access is allowed (see `useAccessControl`). The check
|
|
18560
|
-
* re-runs whenever the params change
|
|
18970
|
+
* re-runs whenever the params change; they are compared by their
|
|
18971
|
+
* `JSON.stringify` form, so an inline object literal does not re-run it on
|
|
18972
|
+
* every render.
|
|
18973
|
+
*
|
|
18974
|
+
* A resolved answer is stored with the control and the params it answers, and
|
|
18975
|
+
* is only returned while both still match. Until 0.81.0 the previous answer was
|
|
18976
|
+
* returned with `isLoading: false` for the render between a params change and
|
|
18977
|
+
* the effect that re-ran the check, so `<Can>` showed the children for the new
|
|
18978
|
+
* resource for one frame on the strength of the old resource's permission. The
|
|
18979
|
+
* first render for new params now reads `{ allowed: false, isLoading: true }`.
|
|
18561
18980
|
*
|
|
18562
18981
|
* @param params - The action/resource being checked.
|
|
18982
|
+
* @returns The answer for exactly these params, or the pending state.
|
|
18563
18983
|
*/
|
|
18564
18984
|
export declare function useCan(params: CanParams): UseCanResult;
|
|
18565
18985
|
|
|
@@ -18899,8 +19319,12 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18899
19319
|
|
|
18900
19320
|
/**
|
|
18901
19321
|
* React hook wrapper around {@link createEventStream}. Connection lifecycle is
|
|
18902
|
-
* tied to the component (and the `url`/`enabled` dependencies);
|
|
18903
|
-
* closes on unmount.
|
|
19322
|
+
* tied to the component (and the `url`/`enabled`/`sessionKey` dependencies);
|
|
19323
|
+
* the stream closes on unmount.
|
|
19324
|
+
*
|
|
19325
|
+
* Pass `sessionKey` (the signed-in user's id) whenever the stream carries one
|
|
19326
|
+
* user's data: a change of account then closes the previous user's stream and
|
|
19327
|
+
* clears `lastMessage`, even when `enabled` never went `false` in between.
|
|
18904
19328
|
*
|
|
18905
19329
|
* A string `url` reopens the stream when it changes. A function `url` does not:
|
|
18906
19330
|
* an inline arrow is a new function every render, and keying on its identity
|
|
@@ -18932,9 +19356,24 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18932
19356
|
*/
|
|
18933
19357
|
export declare function useEventStream<T = unknown>(url: EventStreamUrl, options?: UseEventStreamOptions<T>): UseEventStreamResult<T>;
|
|
18934
19358
|
|
|
18935
|
-
export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange"> {
|
|
19359
|
+
export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange" | "sessionKey"> {
|
|
18936
19360
|
/** When false, the stream is not opened. Useful for "wait for auth". Default: true. */
|
|
18937
19361
|
enabled?: boolean;
|
|
19362
|
+
/**
|
|
19363
|
+
* The session the stream belongs to — the signed-in user's id, typically.
|
|
19364
|
+
*
|
|
19365
|
+
* A change closes the stream, clears `lastMessage` and, while `enabled`,
|
|
19366
|
+
* opens a new connection for the new session (a fresh ticket, for
|
|
19367
|
+
* {@link useTicketEventStream}). Without it, a tab that switches accounts
|
|
19368
|
+
* without passing through `enabled: false` keeps the previous user's
|
|
19369
|
+
* stream open and delivers its events under the new user: the server does
|
|
19370
|
+
* not end an open stream on logout or revocation, so the client has to.
|
|
19371
|
+
*
|
|
19372
|
+
* A frame that arrives between the render that changed the key and the
|
|
19373
|
+
* effect that closes the stream is dropped as well. Default: `undefined`,
|
|
19374
|
+
* which never changes, so the stream follows `url` and `enabled` alone.
|
|
19375
|
+
*/
|
|
19376
|
+
sessionKey?: SessionKey;
|
|
18938
19377
|
}
|
|
18939
19378
|
|
|
18940
19379
|
export declare interface UseEventStreamResult<T> {
|
|
@@ -20958,11 +21397,33 @@ export declare function useThrottle<T>(value: T, delay: number): T;
|
|
|
20958
21397
|
* Reopening on identity would reconnect on every render for a client built
|
|
20959
21398
|
* inline.
|
|
20960
21399
|
*
|
|
21400
|
+
* The stream is bound to a session: the ticket names the channel of the user
|
|
21401
|
+
* who asked for it, the server never ends an open stream on logout, and a tab
|
|
21402
|
+
* that switches accounts without `enabled` going `false` would otherwise keep
|
|
21403
|
+
* delivering the previous user's events. A change of session closes that
|
|
21404
|
+
* stream and asks a ticket for the new one.
|
|
21405
|
+
*
|
|
21406
|
+
* With the `api` of `createTempestAuth` as `client`, that binding is automatic
|
|
21407
|
+
* (since 0.82.0): the session is read from the client — `auth.sessionKey()`,
|
|
21408
|
+
* the lineage `login()` mints — so a switch closes the stream, a token
|
|
21409
|
+
* rotation of the same session does not, and while nobody is signed in the
|
|
21410
|
+
* stream stays `idle` without asking for a ticket. Any other client keeps the
|
|
21411
|
+
* behaviour it had: pass `sessionKey` (the signed-in user's id). A
|
|
21412
|
+
* `sessionKey` passed explicitly always wins over the client's.
|
|
21413
|
+
*
|
|
21414
|
+
* @example
|
|
21415
|
+
* const { status } = useTicketEventStream<Notification>({
|
|
21416
|
+
* client: auth.api,
|
|
21417
|
+
* schema: notificationSchema,
|
|
21418
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
21419
|
+
* });
|
|
21420
|
+
*
|
|
20961
21421
|
* @example
|
|
21422
|
+
* // A client createTempestAuth did not build
|
|
20962
21423
|
* const { status } = useTicketEventStream<Notification>({
|
|
20963
21424
|
* client: api,
|
|
20964
21425
|
* enabled: isAuthenticated,
|
|
20965
|
-
*
|
|
21426
|
+
* sessionKey: user?.id ?? null,
|
|
20966
21427
|
* onMessage: ({ data }) => addNotification(data),
|
|
20967
21428
|
* });
|
|
20968
21429
|
*
|
|
@@ -21184,7 +21645,7 @@ export { useWatch }
|
|
|
21184
21645
|
* for the host component and tears it down on unmount.
|
|
21185
21646
|
*
|
|
21186
21647
|
* Every callback is read through a ref, so `onOpen` / `onMessage` / `onClose` /
|
|
21187
|
-
* `onError` / `onReconnecting` / `onReconnected` / `onLost` always run the
|
|
21648
|
+
* `onError` / `onReconnecting` / `onReconnected` / `onLost` / `getPrincipal` always run the
|
|
21188
21649
|
* latest closure — an inline arrow function is fine and never reopens the
|
|
21189
21650
|
* socket. Connection-shaping options (`protocols`, `maxRetries`,
|
|
21190
21651
|
* `initialBackoff`, `maxBackoff`, `jitter`, `handshakeTimeout`,
|
|
@@ -21275,6 +21736,12 @@ export declare function validateCPF(value: string): boolean;
|
|
|
21275
21736
|
* become `"address.city"`, array entries `"items.0.name"`. The first issue
|
|
21276
21737
|
* per path wins (subsequent ones are dropped to keep error UIs tidy).
|
|
21277
21738
|
*
|
|
21739
|
+
* The map is a plain object, but every key is written as an **own** property
|
|
21740
|
+
* and looked up with `hasOwnProperty`: with `path in errors` and `errors[path] =`
|
|
21741
|
+
* a field named `constructor` or `toString` read as already failed through
|
|
21742
|
+
* `Object.prototype` and lost its message, and an issue a `superRefine` files
|
|
21743
|
+
* under `__proto__` replaced the map's prototype instead of becoming a key.
|
|
21744
|
+
*
|
|
21278
21745
|
* @param schema - zod schema describing the form shape.
|
|
21279
21746
|
* @param values - Raw form values (typed as `unknown`).
|
|
21280
21747
|
* @returns Either `{ success: true, data, errors: {} }` or `{ success: false, errors }`.
|
|
@@ -22381,6 +22848,12 @@ export declare function writeXlsx(headers: readonly string[], rows: readonly (re
|
|
|
22381
22848
|
* `ResolverOptions` is accepted and ignored, because react-hook-form always
|
|
22382
22849
|
* passes the whole object.
|
|
22383
22850
|
*
|
|
22851
|
+
* Errors are written as **own** properties and checked with `hasOwnProperty`.
|
|
22852
|
+
* A plain `errors[path]` read saw `Object.prototype.constructor` for a field
|
|
22853
|
+
* named `constructor`, so `firstError` mode kept the inherited function instead
|
|
22854
|
+
* of the message, and an issue a `superRefine` files under `__proto__` replaced
|
|
22855
|
+
* the map's prototype instead of adding the field.
|
|
22856
|
+
*
|
|
22384
22857
|
* @example
|
|
22385
22858
|
* const form = useForm<LoginForm>({ resolver: zodResolver(loginSchema) });
|
|
22386
22859
|
*/
|