tempest-react-sdk 0.80.0 → 0.82.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 +40 -10
- package/bin/create-tempest-app.e2e.test.mjs +31 -0
- package/bin/create-tempest-app.mjs +11 -1
- package/bin/lib/component/generate.test.mjs +13 -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 +150 -1
- package/bin/lib/openapi/generate.mjs +78 -13
- package/bin/lib/openapi/generate.test.mjs +13 -1
- 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 +234 -122
- 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 +1 -1
- package/dist/br/boleto.cjs.map +1 -1
- package/dist/br/boleto.js +2 -1
- package/dist/br/boleto.js.map +1 -1
- package/dist/br.d.ts +22 -3
- package/dist/components/AuthForm/AuthFieldControl.cjs +2 -0
- package/dist/components/AuthForm/AuthFieldControl.cjs.map +1 -0
- package/dist/components/AuthForm/AuthFieldControl.js +85 -0
- package/dist/components/AuthForm/AuthFieldControl.js.map +1 -0
- package/dist/components/AuthForm/AuthForm.cjs +2 -0
- package/dist/components/AuthForm/AuthForm.cjs.map +1 -0
- package/dist/components/AuthForm/AuthForm.js +83 -0
- package/dist/components/AuthForm/AuthForm.js.map +1 -0
- package/dist/components/AuthForm/AuthForm.module.cjs +3 -0
- package/dist/components/AuthForm/AuthForm.module.cjs.map +1 -0
- package/dist/components/AuthForm/AuthForm.module.js +14 -0
- package/dist/components/AuthForm/AuthForm.module.js.map +1 -0
- package/dist/components/AuthForm/AuthLinks.cjs +2 -0
- package/dist/components/AuthForm/AuthLinks.cjs.map +1 -0
- package/dist/components/AuthForm/AuthLinks.js +32 -0
- package/dist/components/AuthForm/AuthLinks.js.map +1 -0
- package/dist/components/AuthForm/ForgotPasswordForm.cjs +2 -0
- package/dist/components/AuthForm/ForgotPasswordForm.cjs.map +1 -0
- package/dist/components/AuthForm/ForgotPasswordForm.js +32 -0
- package/dist/components/AuthForm/ForgotPasswordForm.js.map +1 -0
- package/dist/components/AuthForm/LoginForm.cjs +2 -0
- package/dist/components/AuthForm/LoginForm.cjs.map +1 -0
- package/dist/components/AuthForm/LoginForm.js +39 -0
- package/dist/components/AuthForm/LoginForm.js.map +1 -0
- package/dist/components/AuthForm/ResetPasswordForm.cjs +2 -0
- package/dist/components/AuthForm/ResetPasswordForm.cjs.map +1 -0
- package/dist/components/AuthForm/ResetPasswordForm.js +39 -0
- package/dist/components/AuthForm/ResetPasswordForm.js.map +1 -0
- package/dist/components/AuthForm/SignUpForm.cjs +2 -0
- package/dist/components/AuthForm/SignUpForm.cjs.map +1 -0
- package/dist/components/AuthForm/SignUpForm.js +32 -0
- package/dist/components/AuthForm/SignUpForm.js.map +1 -0
- package/dist/components/AuthForm/auth-defaults.cjs +2 -0
- package/dist/components/AuthForm/auth-defaults.cjs.map +1 -0
- package/dist/components/AuthForm/auth-defaults.js +54 -0
- package/dist/components/AuthForm/auth-defaults.js.map +1 -0
- package/dist/components/AuthForm/auth-schemas.cjs +2 -0
- package/dist/components/AuthForm/auth-schemas.cjs.map +1 -0
- package/dist/components/AuthForm/auth-schemas.js +26 -0
- package/dist/components/AuthForm/auth-schemas.js.map +1 -0
- package/dist/components/AuthPage/AuthPage.cjs +2 -0
- package/dist/components/AuthPage/AuthPage.cjs.map +1 -0
- package/dist/components/AuthPage/AuthPage.js +97 -0
- package/dist/components/AuthPage/AuthPage.js.map +1 -0
- package/dist/components/AuthPage/AuthPage.module.cjs +3 -0
- package/dist/components/AuthPage/AuthPage.module.cjs.map +1 -0
- package/dist/components/AuthPage/AuthPage.module.js +24 -0
- package/dist/components/AuthPage/AuthPage.module.js.map +1 -0
- 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/FilterBar/filter-apply.cjs +1 -1
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
- package/dist/components/FilterBar/filter-apply.js +7 -7
- 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/index.js +7 -7
- package/dist/forms/masked-inputs.cjs +1 -1
- package/dist/forms/masked-inputs.cjs.map +1 -1
- package/dist/forms/masked-inputs.js +15 -15
- 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 +137 -116
- 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 +140 -134
- 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 +17 -17
- package/dist/http/upload-with-progress.js.map +1 -1
- package/dist/http/use-describe-api-error.cjs +1 -1
- package/dist/http/use-describe-api-error.cjs.map +1 -1
- package/dist/http/use-describe-api-error.js +9 -9
- 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 +108 -68
- 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 +54 -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/styles/AuthForm.css +2 -0
- package/dist/styles/AuthPage.css +2 -0
- package/dist/styles/component/AuthForm.css +9 -0
- package/dist/styles/component/AuthPage.css +29 -0
- package/dist/styles/forms.css +36 -0
- package/dist/styles/manifest.json +63 -0
- package/dist/styles.css +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 +132 -112
- 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 +36 -30
- 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 +93 -28
- 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 +1057 -83
- package/dist/tempest-react-sdk.js +373 -365
- 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/format.cjs +1 -1
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.js +25 -25
- package/dist/utils/numbers.cjs +1 -1
- package/dist/utils/numbers.cjs.map +1 -1
- package/dist/utils/numbers.js +7 -7
- 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/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 +15 -10
|
@@ -15,6 +15,7 @@ import { ComponentType } from 'react';
|
|
|
15
15
|
import { CompositionEventHandler } from 'react';
|
|
16
16
|
import { Control } from 'react-hook-form';
|
|
17
17
|
import { Controller } from 'react-hook-form';
|
|
18
|
+
import { ControllerFieldState } from 'react-hook-form';
|
|
18
19
|
import { ControllerRenderProps } from 'react-hook-form';
|
|
19
20
|
import { createBrowserRouter } from 'react-router';
|
|
20
21
|
import { createHashRouter } from 'react-router';
|
|
@@ -870,7 +871,10 @@ export declare interface ApiClientConfig {
|
|
|
870
871
|
* Never logs a body, a header, or the query string — a bearer token in
|
|
871
872
|
* `Authorization`, a password in a login payload and an `access_token` query
|
|
872
873
|
* param would all end up in whatever the sink writes to. What is logged is
|
|
873
|
-
* the method, the path
|
|
874
|
+
* the method, the path and the numbers. The path is cut at the first `?` or
|
|
875
|
+
* `#`, and an absolute URL loses its `user:password@`, so a query written
|
|
876
|
+
* into the path (`"/files?access_token=…"`) or the signature of a presigned
|
|
877
|
+
* URL stays out just like `params` does.
|
|
874
878
|
*/
|
|
875
879
|
logger?: ApiClientLogger;
|
|
876
880
|
/**
|
|
@@ -962,7 +966,20 @@ export declare interface ApiClientConfig {
|
|
|
962
966
|
* without it, and is exposed the same way.
|
|
963
967
|
*/
|
|
964
968
|
csrf?: boolean | CsrfOptions;
|
|
965
|
-
/**
|
|
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
|
+
*/
|
|
966
983
|
headers?: Record<string, string>;
|
|
967
984
|
/** Optional fetch implementation (defaults to globalThis.fetch). */
|
|
968
985
|
fetcher?: typeof fetch;
|
|
@@ -1783,6 +1800,152 @@ export declare interface AudioRecording {
|
|
|
1783
1800
|
durationMs: number;
|
|
1784
1801
|
}
|
|
1785
1802
|
|
|
1803
|
+
/**
|
|
1804
|
+
* An e-mail field: trimmed and lower-cased *before* it is validated.
|
|
1805
|
+
*
|
|
1806
|
+
* The order is the point. Validating first rejects `" ana@x.com"` pasted with a
|
|
1807
|
+
* trailing space from a password manager, and a backend that compares e-mails
|
|
1808
|
+
* case-sensitively creates a second account for `Ana@x.com`. An empty value gets
|
|
1809
|
+
* its own sentence instead of "e-mail inválido", which reads like an accusation
|
|
1810
|
+
* on a field the user simply has not reached yet.
|
|
1811
|
+
*
|
|
1812
|
+
* @returns A schema producing the normalized address.
|
|
1813
|
+
*/
|
|
1814
|
+
export declare function authEmail(): z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
1815
|
+
|
|
1816
|
+
/**
|
|
1817
|
+
* One entry of an auth form's `fields` list.
|
|
1818
|
+
*
|
|
1819
|
+
* The form is generated from this list, so the app declares *which* fields and
|
|
1820
|
+
* *how they read* — never the markup, the wiring to react-hook-form or the error
|
|
1821
|
+
* slot.
|
|
1822
|
+
*
|
|
1823
|
+
* @typeParam TName - The schema's keys, so a typo in `name` fails to compile.
|
|
1824
|
+
*/
|
|
1825
|
+
export declare interface AuthField<TName extends string = string> {
|
|
1826
|
+
/** Key in the schema and in the submitted values. */
|
|
1827
|
+
name: TName;
|
|
1828
|
+
/** Visible label. Rich content works for `checkbox` (a terms link); keep it text for `pin`. */
|
|
1829
|
+
label: ReactNode;
|
|
1830
|
+
/** Control used to render it. Default `"text"`. */
|
|
1831
|
+
type?: AuthFieldType;
|
|
1832
|
+
/** Placeholder shown while the field is empty. */
|
|
1833
|
+
placeholder?: string;
|
|
1834
|
+
/**
|
|
1835
|
+
* `autocomplete` token. Defaults per type: `email` → `"email"`, `password` →
|
|
1836
|
+
* `"current-password"`, `phone` → `"tel"`. Sign-up and reset presets pass
|
|
1837
|
+
* `"new-password"` so password managers offer to generate one.
|
|
1838
|
+
*/
|
|
1839
|
+
autoComplete?: string;
|
|
1840
|
+
/** Help text under the field, replaced by the error when there is one. */
|
|
1841
|
+
helperText?: ReactNode;
|
|
1842
|
+
/** Marks the control as required (visual hint + native attribute). */
|
|
1843
|
+
required?: boolean;
|
|
1844
|
+
/** `password` only: show the strength meter under the field. */
|
|
1845
|
+
showStrength?: boolean;
|
|
1846
|
+
/** `pin` only: number of cells. Default `6`. */
|
|
1847
|
+
length?: number;
|
|
1848
|
+
/** Render the control yourself — for a field none of the types covers. */
|
|
1849
|
+
render?: (props: AuthFieldRenderProps) => ReactNode;
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
/** The field names a schema accepts. */
|
|
1853
|
+
export declare type AuthFieldName<TSchema extends z.ZodTypeAny> = Extract<keyof z.infer<TSchema>, string>;
|
|
1854
|
+
|
|
1855
|
+
/** What a field's `render` receives: the react-hook-form binding plus the field's own config. */
|
|
1856
|
+
export declare interface AuthFieldRenderProps {
|
|
1857
|
+
/** `name`, `value`, `onChange`, `onBlur` and `ref` — spread or wire them into the control. */
|
|
1858
|
+
field: ControllerRenderProps<FieldValues, string>;
|
|
1859
|
+
/** The field's validation state, including the server error mapped onto it. */
|
|
1860
|
+
fieldState: ControllerFieldState;
|
|
1861
|
+
/** The current error message, already resolved from `fieldState`. */
|
|
1862
|
+
error?: string;
|
|
1863
|
+
/** The config entry this field was declared with. */
|
|
1864
|
+
config: AuthField;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
/**
|
|
1868
|
+
* Which SDK control renders a field.
|
|
1869
|
+
*
|
|
1870
|
+
* `text` and `email` → `Input`, `password` → `PasswordInput`, `phone` / `cpf` /
|
|
1871
|
+
* `cnpj` → the masked inputs, `checkbox` → `Checkbox`, `pin` → `PinInput`. The
|
|
1872
|
+
* list is closed on purpose: these are the controls an auth screen uses, and
|
|
1873
|
+
* anything else goes through `render`.
|
|
1874
|
+
*/
|
|
1875
|
+
export declare type AuthFieldType = "text" | "email" | "password" | "phone" | "cpf" | "cnpj" | "checkbox" | "pin";
|
|
1876
|
+
|
|
1877
|
+
/**
|
|
1878
|
+
* A complete auth form generated from a list of field configs and a zod schema.
|
|
1879
|
+
*
|
|
1880
|
+
* Every hand-built login and sign-up screen repeated the same wiring: a
|
|
1881
|
+
* `useZodForm`, one labelled input per field with its error slot, a password eye,
|
|
1882
|
+
* a submit button disabled while the request runs, and a `catch` that copied the
|
|
1883
|
+
* 422's field messages back onto the inputs. The app now declares *which* fields
|
|
1884
|
+
* and *what happens on submit*; the rest is here, built on the SDK's own controls
|
|
1885
|
+
* and its forms layer (`useZodForm` + `FormProvider` + `FormField`).
|
|
1886
|
+
*
|
|
1887
|
+
* Errors thrown by `onSubmit` are shown, never rethrown — a rethrow from a submit
|
|
1888
|
+
* handler is an unhandled rejection with nowhere to go. A `TempestApiError` whose
|
|
1889
|
+
* `fields` name fields of this form marks them; anything else, and any field
|
|
1890
|
+
* message that matched no declared field, goes to an `Alert` above the fields,
|
|
1891
|
+
* worded by `describeApiError`. Pass `onError` to log.
|
|
1892
|
+
*
|
|
1893
|
+
* @example
|
|
1894
|
+
* const schema = z.object({ email: z.email("E-mail inválido") });
|
|
1895
|
+
* <AuthForm
|
|
1896
|
+
* schema={schema}
|
|
1897
|
+
* fields={[{ name: "email", type: "email", label: "E-mail" }]}
|
|
1898
|
+
* submitLabel="Continuar"
|
|
1899
|
+
* onSubmit={async (values) => { await api.post("/auth/magic-link", { body: values }); }}
|
|
1900
|
+
* />
|
|
1901
|
+
*/
|
|
1902
|
+
export declare function AuthForm<TSchema extends z.ZodTypeAny>({ schema, fields, onSubmit, submitLabel, defaultValues, beforeSubmit, afterSubmit, social, labels, errorOptions, onError, className, }: AuthFormProps<TSchema>): ReactNode;
|
|
1903
|
+
|
|
1904
|
+
/** Fixed sentences of {@link AuthFormProps}, PT-BR by default. */
|
|
1905
|
+
export declare interface AuthFormLabels {
|
|
1906
|
+
/** Text of the divider drawn above the `social` slot. Default `"ou"`. */
|
|
1907
|
+
divider: string;
|
|
1908
|
+
/**
|
|
1909
|
+
* Fallback sentence of the error alert, when the thrown error carries nothing
|
|
1910
|
+
* better. Default `"Não foi possível concluir agora. Tente de novo."`.
|
|
1911
|
+
*/
|
|
1912
|
+
error: string;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
export declare interface AuthFormProps<TSchema extends z.ZodTypeAny> {
|
|
1916
|
+
/** Zod schema validating the values; its messages are what each field shows. */
|
|
1917
|
+
schema: TSchema;
|
|
1918
|
+
/** The fields, in display order. */
|
|
1919
|
+
fields: readonly AuthField<AuthFieldName<TSchema>>[];
|
|
1920
|
+
/**
|
|
1921
|
+
* Called with the validated values. Throw to fail: a `TempestApiError` whose
|
|
1922
|
+
* `fields` name fields of this form marks those fields; any other error shows
|
|
1923
|
+
* an alert above the form.
|
|
1924
|
+
*/
|
|
1925
|
+
onSubmit: (values: z.infer<TSchema>) => Promise<void> | void;
|
|
1926
|
+
/** Submit button content. Default `"Enviar"`. */
|
|
1927
|
+
submitLabel?: ReactNode;
|
|
1928
|
+
/** Initial values. Fields left out start as `""` (`false` for checkboxes). */
|
|
1929
|
+
defaultValues?: Partial<z.input<TSchema>>;
|
|
1930
|
+
/** Content between the fields and the submit button — the "forgot password" link. */
|
|
1931
|
+
beforeSubmit?: ReactNode;
|
|
1932
|
+
/** Content after the submit button — the "no account? sign up" line. */
|
|
1933
|
+
afterSubmit?: ReactNode;
|
|
1934
|
+
/** Social sign-in buttons. Rendered under a divider reading `labels.divider`. */
|
|
1935
|
+
social?: ReactNode;
|
|
1936
|
+
/** Overrides for the fixed sentences. */
|
|
1937
|
+
labels?: Partial<AuthFormLabels>;
|
|
1938
|
+
/** Passed to `describeApiError` to word the alert — map error `codes`, `statuses`. */
|
|
1939
|
+
errorOptions?: DescribeApiErrorOptions;
|
|
1940
|
+
/** Called with every error `onSubmit` threw, after it is shown — for logging. */
|
|
1941
|
+
onError?: (error: unknown) => void;
|
|
1942
|
+
/** Class name for the `<form>`. */
|
|
1943
|
+
className?: string;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
/** The value object a schema produces, as react-hook-form sees it. */
|
|
1947
|
+
export declare type AuthFormValues<TSchema extends z.ZodTypeAny> = z.infer<TSchema> & FieldValues;
|
|
1948
|
+
|
|
1786
1949
|
/**
|
|
1787
1950
|
* Router-agnostic auth gate. The caller decides what to render in either
|
|
1788
1951
|
* branch — typically `<Outlet />` for protected layouts and `<Navigate />` for
|
|
@@ -1807,6 +1970,126 @@ export declare interface AuthGuardProps {
|
|
|
1807
1970
|
fallback: ReactNode;
|
|
1808
1971
|
}
|
|
1809
1972
|
|
|
1973
|
+
/**
|
|
1974
|
+
* The layout shell of a sign-in, sign-up or password-recovery screen.
|
|
1975
|
+
*
|
|
1976
|
+
* Every app was hand-building the same page around its form: a colored top with
|
|
1977
|
+
* the logo and a back button over a white sheet with rounded top corners on
|
|
1978
|
+
* mobile, a 50/50 brand panel and form on desktop, a "Bem-vindo!" heading. This
|
|
1979
|
+
* component is that page, so the app passes only the brand and the form.
|
|
1980
|
+
*
|
|
1981
|
+
* The switch between the two layouts is a JavaScript media query, not a CSS
|
|
1982
|
+
* `@media` rule, because the breakpoint is a prop: a CSS media query cannot read a
|
|
1983
|
+
* custom property. `useMediaQuery` evaluates synchronously on the first render, so
|
|
1984
|
+
* a client-rendered page does not flash the wrong layout.
|
|
1985
|
+
*
|
|
1986
|
+
* @example
|
|
1987
|
+
* <AuthPage brand={<img src="/logo.svg" alt="Acme" />} back="/" title="Bem-vindo!">
|
|
1988
|
+
* <LoginForm onSubmit={signIn} links={{ forgotPassword: "/recuperar", signUp: "/cadastro" }} />
|
|
1989
|
+
* </AuthPage>
|
|
1990
|
+
*/
|
|
1991
|
+
export declare function AuthPage({ brand, title, subtitle, aside, variant, breakpoint, back, footer, headingLevel, as, children, className, style, ...props }: AuthPageProps): ReactNode;
|
|
1992
|
+
|
|
1993
|
+
/** The brand panel of a `split` page — the colored half on desktop, the colored top on mobile. */
|
|
1994
|
+
export declare interface AuthPageAside {
|
|
1995
|
+
/**
|
|
1996
|
+
* Any CSS `background` value: a color, a token, a gradient, an image.
|
|
1997
|
+
* Defaults to `var(--tempest-primary)`, so a themed app gets its brand color
|
|
1998
|
+
* without passing anything.
|
|
1999
|
+
*/
|
|
2000
|
+
background?: string;
|
|
2001
|
+
/**
|
|
2002
|
+
* Text color over that background. Defaults to `var(--tempest-text-on-primary)`,
|
|
2003
|
+
* which is only right while the background is the primary color — set it
|
|
2004
|
+
* together with a custom `background` so the back button and the app name
|
|
2005
|
+
* keep their contrast.
|
|
2006
|
+
*/
|
|
2007
|
+
color?: string;
|
|
2008
|
+
/** Extra content under the brand on the panel: a tagline, an illustration. */
|
|
2009
|
+
content?: ReactNode;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
/** The back action, as an object when the label or the behavior is not the default. */
|
|
2013
|
+
export declare interface AuthPageBackAction {
|
|
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
|
+
*/
|
|
2019
|
+
to?: string;
|
|
2020
|
+
/** Visible label (and accessible name). Default `"Voltar"`. */
|
|
2021
|
+
label?: string;
|
|
2022
|
+
/** Click handler — used alone (a `<button>`) or together with `to`. */
|
|
2023
|
+
onClick?: () => void;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
/** Heading level of the page title. */
|
|
2027
|
+
export declare type AuthPageHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
2028
|
+
|
|
2029
|
+
export declare interface AuthPageProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
2030
|
+
/** Logo and/or app name, shown on the brand panel (split) or at the top of the card. */
|
|
2031
|
+
brand?: ReactNode;
|
|
2032
|
+
/** Page title, rendered as a heading — e.g. `"Bem-vindo!"`. */
|
|
2033
|
+
title?: ReactNode;
|
|
2034
|
+
/** Line under the title — e.g. `"Entre com sua conta para continuar"`. */
|
|
2035
|
+
subtitle?: ReactNode;
|
|
2036
|
+
/** Brand panel colors and extra content. */
|
|
2037
|
+
aside?: AuthPageAside;
|
|
2038
|
+
/**
|
|
2039
|
+
* `split` (default): colored top + rounded white sheet below `breakpoint`,
|
|
2040
|
+
* 50/50 brand panel and form at or above it. `card`: one centered card at
|
|
2041
|
+
* every width — the internal-panel login.
|
|
2042
|
+
*/
|
|
2043
|
+
variant?: AuthPageVariant;
|
|
2044
|
+
/**
|
|
2045
|
+
* Viewport width, in px, at which `split` turns into two columns. Default
|
|
2046
|
+
* `768`, the width every hand-built auth screen this replaces switched at —
|
|
2047
|
+
* deliberately not the `1024` of `useBreakpoint`, which is about navigation
|
|
2048
|
+
* chrome, not about whether a form fits beside a brand panel.
|
|
2049
|
+
*/
|
|
2050
|
+
breakpoint?: number;
|
|
2051
|
+
/** Back action: a route string, or an object with `to`/`label`/`onClick`. Omit to hide it. */
|
|
2052
|
+
back?: string | AuthPageBackAction;
|
|
2053
|
+
/** Content under the form, inside the sheet or card — legal text, a secondary link. */
|
|
2054
|
+
footer?: ReactNode;
|
|
2055
|
+
/** Heading level of `title`. Default `1`, since the auth screen is usually the whole page. */
|
|
2056
|
+
headingLevel?: AuthPageHeadingLevel;
|
|
2057
|
+
/**
|
|
2058
|
+
* Root element. Default `"main"`, the page's main landmark. Use `"div"` when
|
|
2059
|
+
* the page is rendered inside a layout that already owns a `<main>` — two
|
|
2060
|
+
* nested main landmarks are an accessibility violation.
|
|
2061
|
+
*/
|
|
2062
|
+
as?: "main" | "div";
|
|
2063
|
+
/** The form — usually an `AuthForm` or one of its presets. */
|
|
2064
|
+
children?: ReactNode;
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
/** How the page is laid out: brand panel beside the form, or one centered card. */
|
|
2068
|
+
export declare type AuthPageVariant = "split" | "card";
|
|
2069
|
+
|
|
2070
|
+
/**
|
|
2071
|
+
* A password field with the minimum length every Tempest backend enforces.
|
|
2072
|
+
*
|
|
2073
|
+
* @param message - Sentence shown below 8 characters.
|
|
2074
|
+
* @returns The password schema.
|
|
2075
|
+
*/
|
|
2076
|
+
export declare function authPassword(message?: string): z.ZodString;
|
|
2077
|
+
|
|
2078
|
+
/**
|
|
2079
|
+
* Props every preset (`LoginForm`, `SignUpForm`, …) shares.
|
|
2080
|
+
*
|
|
2081
|
+
* `schema` and `fields` become optional — the preset ships both — and the slots
|
|
2082
|
+
* around the submit button are the preset's to fill, from its `links`.
|
|
2083
|
+
*
|
|
2084
|
+
* @typeParam TSchema - The schema in use; the preset's default when none is passed.
|
|
2085
|
+
*/
|
|
2086
|
+
export declare interface AuthPresetProps<TSchema extends z.ZodTypeAny> extends Omit<AuthFormProps<TSchema>, "schema" | "fields" | "labels" | "beforeSubmit" | "afterSubmit"> {
|
|
2087
|
+
/** Replaces the preset's schema. Pair it with `fields` when it adds or renames keys. */
|
|
2088
|
+
schema?: TSchema;
|
|
2089
|
+
/** Replaces the preset's field list. */
|
|
2090
|
+
fields?: readonly AuthField<AuthFieldName<TSchema>>[];
|
|
2091
|
+
}
|
|
2092
|
+
|
|
1810
2093
|
export declare interface AuthState<TUser> {
|
|
1811
2094
|
user: TUser | null;
|
|
1812
2095
|
token: string | null;
|
|
@@ -2376,6 +2659,12 @@ export declare interface BreadcrumbItem {
|
|
|
2376
2659
|
* Hierarchical navigation breadcrumbs. The last item is rendered as plain
|
|
2377
2660
|
* text with `aria-current="page"`. Items with neither `href` nor `onClick`
|
|
2378
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.
|
|
2379
2668
|
*/
|
|
2380
2669
|
export declare function Breadcrumbs({ items, separator, className }: BreadcrumbsProps): JSX.Element;
|
|
2381
2670
|
|
|
@@ -2523,6 +2812,13 @@ export declare function buildOpenInChromeIntent(): string | null;
|
|
|
2523
2812
|
* link gets `aria-disabled="true"`, `role="link"`, `tabIndex={-1}`, no `href`, and
|
|
2524
2813
|
* its click and middle-click cancelled.
|
|
2525
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
|
+
*
|
|
2526
2822
|
* To style another element — a react-router `Link` — use {@link ButtonSlot}. It is
|
|
2527
2823
|
* a separate component, not an `asChild` prop, so an app that never uses it does
|
|
2528
2824
|
* not ship the prop merge and ref composition it needs.
|
|
@@ -3911,7 +4207,21 @@ export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value
|
|
|
3911
4207
|
* destination of a credentialed request could come from a value read off the
|
|
3912
4208
|
* network. A request to another origin still goes out; it goes without the
|
|
3913
4209
|
* header, and a development build says so once. Declare the exceptions in
|
|
3914
|
-
* {@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.
|
|
3915
4225
|
*
|
|
3916
4226
|
* **CSRF** is off unless you set `csrf`. With it, every unsafe request (anything
|
|
3917
4227
|
* but `GET`/`HEAD`/`OPTIONS`/`TRACE`) echoes the `csrf_token` cookie in an
|
|
@@ -4239,7 +4549,13 @@ export declare function createDataProvider(client: ApiClient, options?: DataProv
|
|
|
4239
4549
|
*
|
|
4240
4550
|
* When `url` is a function it is called before every connection, so a
|
|
4241
4551
|
* reconnect presents a fresh credential instead of the one that expired. A
|
|
4242
|
-
* 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.
|
|
4243
4559
|
*
|
|
4244
4560
|
* @param url - Full SSE endpoint URL, or a function returning it per connection.
|
|
4245
4561
|
* @param options - Stream configuration and callbacks.
|
|
@@ -4307,6 +4623,30 @@ export declare interface CreateEventStreamOptions<T> {
|
|
|
4307
4623
|
* URL that never resolved never had an `EventSource`.
|
|
4308
4624
|
*/
|
|
4309
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;
|
|
4310
4650
|
/**
|
|
4311
4651
|
* Whether a URL-resolution failure is worth another attempt. Default: always.
|
|
4312
4652
|
*
|
|
@@ -5252,6 +5592,22 @@ export declare interface CreateStorePersistOptions<T> {
|
|
|
5252
5592
|
* without a working revocation, that boot `refresh()` restores the previous
|
|
5253
5593
|
* account for whoever uses the browser next.
|
|
5254
5594
|
*
|
|
5595
|
+
* With `storage: "local"` the session belongs to the **origin**, not the tab:
|
|
5596
|
+
* every tab reads and writes the same keys and follows what another tab wrote
|
|
5597
|
+
* — on the `storage` event and, before any refresh, `logout()` or ending of
|
|
5598
|
+
* the session, by comparing the stored session with the one it holds. A
|
|
5599
|
+
* rotation elsewhere is adopted; a logout or another account's login
|
|
5600
|
+
* elsewhere ends the session here too, with `onSessionEnd` told it happened
|
|
5601
|
+
* `elsewhere`. Before 0.81.0 a tab left open after logout kept account A and,
|
|
5602
|
+
* on its next `401`, redeemed account B's refresh token from the shared
|
|
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.
|
|
5610
|
+
*
|
|
5255
5611
|
* Refreshes are collapsed per rotation, not just per overlap: a `401` whose
|
|
5256
5612
|
* request left with a token that has since been replaced in the same session
|
|
5257
5613
|
* replays with the new token and refreshes nothing. Three expired requests take
|
|
@@ -5316,9 +5672,14 @@ export declare interface CreateTempestAuthOptions<TUser> {
|
|
|
5316
5672
|
* while it is in flight waits for it, because the logout response clears
|
|
5317
5673
|
* the auth cookies and would otherwise clear the new account's.
|
|
5318
5674
|
*
|
|
5319
|
-
*
|
|
5320
|
-
*
|
|
5321
|
-
*
|
|
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.
|
|
5322
5683
|
*
|
|
5323
5684
|
* Overlapping sign-outs each send their own revocation, and `login()` waits
|
|
5324
5685
|
* for all of them — at most 10 seconds, so one that
|
|
@@ -5529,9 +5890,23 @@ export declare interface CreateThemeOptions {
|
|
|
5529
5890
|
* cookie) on the ticket request, and the ticket in the URL opens that stream
|
|
5530
5891
|
* and nothing else.
|
|
5531
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
|
+
*
|
|
5532
5899
|
* @example
|
|
5533
5900
|
* const stream = createTicketEventStream<Notification>({
|
|
5901
|
+
* client: auth.api,
|
|
5902
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
5903
|
+
* });
|
|
5904
|
+
*
|
|
5905
|
+
* @example
|
|
5906
|
+
* // A client createTempestAuth did not build
|
|
5907
|
+
* const stream = createTicketEventStream<Notification>({
|
|
5534
5908
|
* client: api,
|
|
5909
|
+
* sessionKey: () => useAuthStore.getState().user?.id ?? null,
|
|
5535
5910
|
* onMessage: ({ data }) => addNotification(data),
|
|
5536
5911
|
* onUrlError: (error) => toast.error(describeApiError(error)),
|
|
5537
5912
|
* });
|
|
@@ -5715,6 +6090,24 @@ export declare interface CreateWebSocketOptions<T> {
|
|
|
5715
6090
|
queueWhileClosed?: boolean;
|
|
5716
6091
|
/** Cap on buffered payloads when `queueWhileClosed` is on. Default: 100. */
|
|
5717
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;
|
|
5718
6111
|
/** Parse incoming frames. Default: JSON with raw-string fallback. */
|
|
5719
6112
|
parser?: (raw: string) => T;
|
|
5720
6113
|
/**
|
|
@@ -6517,10 +6910,18 @@ export declare function decodeJWT(token: string): DecodedJWT;
|
|
|
6517
6910
|
* compression was enabled — or by a write that fell back after `gzipSync`
|
|
6518
6911
|
* failed — still read back.
|
|
6519
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
|
+
*
|
|
6520
6920
|
* @typeParam T - The expected value shape.
|
|
6521
6921
|
* @param raw - The stored string.
|
|
6522
6922
|
* @returns The decoded value.
|
|
6523
|
-
* @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.
|
|
6524
6925
|
*/
|
|
6525
6926
|
export declare function decompressFromString<T>(raw: string): T;
|
|
6526
6927
|
|
|
@@ -6531,6 +6932,13 @@ export declare function decompressFromString<T>(raw: string): T;
|
|
|
6531
6932
|
* - Arrays and non-plain values (dates, class instances, primitives) replace
|
|
6532
6933
|
* the target value entirely — they are not merged element by element.
|
|
6533
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.
|
|
6534
6942
|
*
|
|
6535
6943
|
* @example
|
|
6536
6944
|
* deepMerge(
|
|
@@ -6554,6 +6962,9 @@ export declare function deepMerge<T>(target: T, source: Partial<T>): T;
|
|
|
6554
6962
|
*/
|
|
6555
6963
|
export declare const DEFAULT_API_ERROR_STRINGS: ApiErrorStrings;
|
|
6556
6964
|
|
|
6965
|
+
/** PT-BR defaults of {@link AuthFormLabels}. */
|
|
6966
|
+
export declare const DEFAULT_AUTH_FORM_LABELS: AuthFormLabels;
|
|
6967
|
+
|
|
6557
6968
|
/**
|
|
6558
6969
|
* What a scanner looks for when you do not say.
|
|
6559
6970
|
*
|
|
@@ -7890,6 +8301,51 @@ declare type FloatingActionButtonVariant = "primary" | "surface";
|
|
|
7890
8301
|
*/
|
|
7891
8302
|
export declare function For<T>({ each, children, fallback }: ForProps<T>): ReactNode;
|
|
7892
8303
|
|
|
8304
|
+
/** Default fields of `ForgotPasswordForm`: the e-mail, with a line saying what happens next. */
|
|
8305
|
+
export declare const FORGOT_PASSWORD_FIELDS: readonly AuthField<"email">[];
|
|
8306
|
+
|
|
8307
|
+
/**
|
|
8308
|
+
* "Forgot password" form: the e-mail the reset link goes to.
|
|
8309
|
+
*
|
|
8310
|
+
* The confirmation screen after a successful submit is the app's call — most
|
|
8311
|
+
* backends answer the same whether or not the address exists, so the copy
|
|
8312
|
+
* belongs next to the backend's policy, not here.
|
|
8313
|
+
*
|
|
8314
|
+
* @example
|
|
8315
|
+
* const [sent, setSent] = useState(false);
|
|
8316
|
+
* <ForgotPasswordForm
|
|
8317
|
+
* onSubmit={async (values) => { await api.post("/auth/forgot-password", { body: values }); setSent(true); }}
|
|
8318
|
+
* links={{ signIn: "/login" }}
|
|
8319
|
+
* />
|
|
8320
|
+
*/
|
|
8321
|
+
export declare function ForgotPasswordForm<TSchema extends z.ZodTypeAny = typeof forgotPasswordSchema>({ schema, fields, links, labels, submitLabel, ...props }: ForgotPasswordFormProps<TSchema>): ReactNode;
|
|
8322
|
+
|
|
8323
|
+
/** Sentences of {@link ForgotPasswordForm}, PT-BR by default. */
|
|
8324
|
+
export declare interface ForgotPasswordFormLabels extends AuthFormLabels {
|
|
8325
|
+
/** Default `"Lembrou a senha?"`. */
|
|
8326
|
+
signInPrompt: string;
|
|
8327
|
+
/** Default `"Entrar"`. */
|
|
8328
|
+
signIn: string;
|
|
8329
|
+
}
|
|
8330
|
+
|
|
8331
|
+
/** Routes the forgot-password form links to. */
|
|
8332
|
+
export declare interface ForgotPasswordFormLinks {
|
|
8333
|
+
/** "Entrar" link, under the form. */
|
|
8334
|
+
signIn?: string;
|
|
8335
|
+
}
|
|
8336
|
+
|
|
8337
|
+
export declare interface ForgotPasswordFormProps<TSchema extends z.ZodTypeAny = typeof forgotPasswordSchema> extends AuthPresetProps<TSchema> {
|
|
8338
|
+
/** Where the links go. */
|
|
8339
|
+
links?: ForgotPasswordFormLinks;
|
|
8340
|
+
/** Overrides for the fixed sentences. */
|
|
8341
|
+
labels?: Partial<ForgotPasswordFormLabels>;
|
|
8342
|
+
}
|
|
8343
|
+
|
|
8344
|
+
/** Default schema of `ForgotPasswordForm`: the e-mail the reset link goes to. */
|
|
8345
|
+
export declare const forgotPasswordSchema: z.ZodObject<{
|
|
8346
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
8347
|
+
}, z.core.$strip>;
|
|
8348
|
+
|
|
7893
8349
|
/**
|
|
7894
8350
|
* Form wrapper with a built-in layout variant. Replaces ad-hoc `<form>` +
|
|
7895
8351
|
* `<Stack>` / `<Grid>` boilerplate; pair with [[FormRow]], [[FormSection]],
|
|
@@ -7922,7 +8378,7 @@ export declare type FormActionsAlign = "start" | "center" | "end" | "between";
|
|
|
7922
8378
|
export declare interface FormActionsProps extends HTMLAttributes<HTMLDivElement> {
|
|
7923
8379
|
/** Horizontal alignment of buttons. Default `end`. */
|
|
7924
8380
|
align?: FormActionsAlign;
|
|
7925
|
-
/** 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. */
|
|
7926
8382
|
gap?: number | string;
|
|
7927
8383
|
}
|
|
7928
8384
|
|
|
@@ -8272,7 +8728,7 @@ export { FormProvider }
|
|
|
8272
8728
|
export declare function FormRow({ gap, className, style, children, ...props }: FormRowProps): JSX.Element;
|
|
8273
8729
|
|
|
8274
8730
|
export declare interface FormRowProps extends HTMLAttributes<HTMLDivElement> {
|
|
8275
|
-
/** 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. */
|
|
8276
8732
|
gap?: number | string;
|
|
8277
8733
|
}
|
|
8278
8734
|
|
|
@@ -8395,7 +8851,14 @@ export declare interface GetListParams {
|
|
|
8395
8851
|
field: string;
|
|
8396
8852
|
order?: "asc" | "desc";
|
|
8397
8853
|
};
|
|
8398
|
-
/**
|
|
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
|
+
*/
|
|
8399
8862
|
filters?: DataFilters;
|
|
8400
8863
|
}
|
|
8401
8864
|
|
|
@@ -8444,7 +8907,7 @@ export declare function getThemePreset(name: string): CreateThemeOptions | undef
|
|
|
8444
8907
|
* />
|
|
8445
8908
|
* </GoogleOAuthProvider>
|
|
8446
8909
|
*/
|
|
8447
|
-
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;
|
|
8448
8911
|
|
|
8449
8912
|
export declare interface GoogleSignInProps {
|
|
8450
8913
|
/**
|
|
@@ -8471,6 +8934,16 @@ export declare interface GoogleSignInProps {
|
|
|
8471
8934
|
disableOneTap?: boolean;
|
|
8472
8935
|
/** Optional `width` override (px) — Google's button is fixed-width. */
|
|
8473
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;
|
|
8474
8947
|
/** Optional className applied to the wrapper. */
|
|
8475
8948
|
className?: string;
|
|
8476
8949
|
/** Optional inline style applied to the wrapper. */
|
|
@@ -8491,7 +8964,7 @@ export declare function Grid({ columns, gap, className, style, children, ...prop
|
|
|
8491
8964
|
export declare interface GridProps extends HTMLAttributes<HTMLDivElement> {
|
|
8492
8965
|
/** Number of columns or a custom `grid-template-columns` value. Accepts responsive object. */
|
|
8493
8966
|
columns?: ResponsiveValue<number | string>;
|
|
8494
|
-
/** 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. */
|
|
8495
8968
|
gap?: ResponsiveValue<number | string>;
|
|
8496
8969
|
children?: ReactNode;
|
|
8497
8970
|
}
|
|
@@ -8946,6 +9419,43 @@ export declare interface InstallBackgroundSyncOptions {
|
|
|
8946
9419
|
* persisting and replaying every header, credentials included.
|
|
8947
9420
|
*/
|
|
8948
9421
|
credentialHeaders?: readonly string[];
|
|
9422
|
+
/**
|
|
9423
|
+
* Origins besides the worker's own that a replayed request may carry a
|
|
9424
|
+
* credential header to — typically the API host when it is not the app's
|
|
9425
|
+
* origin (`["https://api.acme.com"]`). Default `[]`: only the worker's origin.
|
|
9426
|
+
*
|
|
9427
|
+
* A credential re-applied at replay comes from the page, so it is the app's
|
|
9428
|
+
* credential, whatever the request originally carried under the same header
|
|
9429
|
+
* name. Before 0.81.0 the worker checked only the name, and a mutation to a
|
|
9430
|
+
* third party that failed offline carrying that party's `Authorization` was
|
|
9431
|
+
* replayed to it with the app's bearer (#523). Now, with the rule
|
|
9432
|
+
* `isTrustedCredentialTarget` enforces on the live `ApiClient`:
|
|
9433
|
+
* - an entry that carried a credential header to an origin outside this
|
|
9434
|
+
* scope is dropped before `beforeReplay` runs — re-sending it without the
|
|
9435
|
+
* credential would be a request the app never made, and with the app's
|
|
9436
|
+
* credential, a leak;
|
|
9437
|
+
* - a request returned by `beforeReplay` (custom or default) that carries a
|
|
9438
|
+
* header from `credentialHeaders` to an origin outside this scope is
|
|
9439
|
+
* dropped instead of sent.
|
|
9440
|
+
*
|
|
9441
|
+
* Both drops warn once per origin per replay in development builds. Entries
|
|
9442
|
+
* with no credential header are not affected: the browser attaches that
|
|
9443
|
+
* origin's own cookies, as it did on the original attempt.
|
|
9444
|
+
*/
|
|
9445
|
+
trustedOrigins?: readonly string[];
|
|
9446
|
+
/**
|
|
9447
|
+
* How an `"unknown"` owner is handled on an entry with no stripped
|
|
9448
|
+
* credentials (see {@link BackgroundSyncOwnerPolicy}). Default `"strict"`.
|
|
9449
|
+
*
|
|
9450
|
+
* `"lenient"` restores the replay-as-is of 0.77.0 and earlier for an app without sign-in,
|
|
9451
|
+
* where no page ever reports a principal. Do not use it with a cookie
|
|
9452
|
+
* session: the browser attaches on replay the cookie of whoever is signed in
|
|
9453
|
+
* at that moment, so a mutation queued by A whose owner was never stamped
|
|
9454
|
+
* (issuing tab closed, empty `clientId`, stamp lost, legacy entry) goes out
|
|
9455
|
+
* with B's session. Entries with stripped credentials ask the pages either
|
|
9456
|
+
* way. Ignored when a custom `beforeReplay` is given.
|
|
9457
|
+
*/
|
|
9458
|
+
ownerPolicy?: BackgroundSyncOwnerPolicy;
|
|
8949
9459
|
/**
|
|
8950
9460
|
* Prepare each queued request right before it is replayed: return the
|
|
8951
9461
|
* request to send (typically with the current credentials applied) or
|
|
@@ -8973,20 +9483,11 @@ export declare interface InstallBackgroundSyncOptions {
|
|
|
8973
9483
|
* `maxRetentionMinutes` (and warns once per replay in development builds) —
|
|
8974
9484
|
* so a page that never calls {@link provideBackgroundSyncCredentials} leaves
|
|
8975
9485
|
* every entry it queued `"unknown"`, and none of them is replayed.
|
|
8976
|
-
*/
|
|
8977
|
-
/**
|
|
8978
|
-
* How an `"unknown"` owner is handled on an entry with no stripped
|
|
8979
|
-
* credentials (see {@link BackgroundSyncOwnerPolicy}). Default `"strict"`.
|
|
8980
9486
|
*
|
|
8981
|
-
*
|
|
8982
|
-
*
|
|
8983
|
-
*
|
|
8984
|
-
* at that moment, so a mutation queued by A whose owner was never stamped
|
|
8985
|
-
* (issuing tab closed, empty `clientId`, stamp lost, legacy entry) goes out
|
|
8986
|
-
* with B's session. Entries with stripped credentials ask the pages either
|
|
8987
|
-
* way. Ignored when a custom `beforeReplay` is given.
|
|
9487
|
+
* Whatever the hook returns is still held to `trustedOrigins`: a credential
|
|
9488
|
+
* header bound for an origin outside the worker's own and `trustedOrigins` is
|
|
9489
|
+
* never sent.
|
|
8988
9490
|
*/
|
|
8989
|
-
ownerPolicy?: BackgroundSyncOwnerPolicy;
|
|
8990
9491
|
beforeReplay?: (request: Request, context: BackgroundSyncReplayContext) => Request | null | Promise<Request | null>;
|
|
8991
9492
|
}
|
|
8992
9493
|
|
|
@@ -9141,7 +9642,9 @@ export declare type InstallMethod = "native" | "ios" | "manual" | "none";
|
|
|
9141
9642
|
*
|
|
9142
9643
|
* A click on an action button opens that action's URL (see
|
|
9143
9644
|
* {@link PushNotificationAction.url}); a click on the body, or on an action
|
|
9144
|
-
* 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.
|
|
9145
9648
|
*/
|
|
9146
9649
|
export declare function installNotificationClickHandler(options?: InstallNotificationClickHandlerOptions): void;
|
|
9147
9650
|
|
|
@@ -9150,6 +9653,12 @@ export declare interface InstallNotificationClickHandlerOptions {
|
|
|
9150
9653
|
* Resolve the destination URL from the notification data and the clicked
|
|
9151
9654
|
* action id (`""` or `undefined` for a click on the body). Default: the
|
|
9152
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 `"/"`.
|
|
9153
9662
|
*/
|
|
9154
9663
|
resolveUrl?: (data: unknown, action: string | undefined) => string;
|
|
9155
9664
|
}
|
|
@@ -9196,8 +9705,9 @@ export declare interface InstallPrecacheOptions {
|
|
|
9196
9705
|
* Every `NotificationOptions` member the payload carries is forwarded —
|
|
9197
9706
|
* `actions`, `requireInteraction`, `vibrate`, `silent`, `renotify`,
|
|
9198
9707
|
* `timestamp`, `dir` and `lang` alongside `body`, `icon`, `badge`, `image` and
|
|
9199
|
-
* `tag`. `data` receives the top-level `url`
|
|
9200
|
-
*
|
|
9708
|
+
* `tag`. `data` receives the payload's own `data`, then the top-level `url`
|
|
9709
|
+
* (default `"/"`) and `actionUrls` mapping each action id to its `url` — in that
|
|
9710
|
+
* order, so `payload.data` cannot override where a click goes.
|
|
9201
9711
|
*/
|
|
9202
9712
|
export declare function installPushHandler(options?: InstallPushHandlerOptions): void;
|
|
9203
9713
|
|
|
@@ -9221,9 +9731,10 @@ export declare interface InstallPushHandlerOptions {
|
|
|
9221
9731
|
* `respondWith`), so a later {@link installPrecache} can handle them.
|
|
9222
9732
|
*
|
|
9223
9733
|
* A request carrying a credential header (`Authorization`, `X-Api-Key`, … — the
|
|
9224
|
-
* route's `credentialHeaders`)
|
|
9734
|
+
* route's `credentialHeaders`), or a CORS `fetch` sent with
|
|
9735
|
+
* `credentials: "include"`, is also left untouched unless its route sets
|
|
9225
9736
|
* `cacheAuthenticated`, and a response with `Cache-Control: no-store`
|
|
9226
|
-
* (or `private`, without that opt-in) is served but never stored. `maxAgeSeconds`
|
|
9737
|
+
* (or `private`, without that opt-in) or `Vary: *` is served but never stored. `maxAgeSeconds`
|
|
9227
9738
|
* applies to every read, including the offline fallback: an expired entry is a
|
|
9228
9739
|
* miss, never a last resort. Under `rangeRequests`, the full resource is cached
|
|
9229
9740
|
* once (the `Range` header stripped) and each range is sliced from it.
|
|
@@ -9620,11 +10131,13 @@ declare type IssuePathSegment = PropertyKey | {
|
|
|
9620
10131
|
* rather than the request blocked: the upload still goes through, it just goes
|
|
9621
10132
|
* without the API's bearer token.
|
|
9622
10133
|
*
|
|
9623
|
-
* Both sides are resolved
|
|
9624
|
-
*
|
|
9625
|
-
*
|
|
9626
|
-
*
|
|
9627
|
-
*
|
|
10134
|
+
* Both sides are resolved first, so a relative `baseURL` or `endpoint` — the
|
|
10135
|
+
* shape behind a dev-server or reverse proxy — compares equal to the absolute
|
|
10136
|
+
* URL the request actually goes to. The target resolves against the document
|
|
10137
|
+
* base URL, where the transport sends it; the reference against the page's
|
|
10138
|
+
* own address, which a `<base href>` cannot move. Outside a browsing context a
|
|
10139
|
+
* relative target is allowed — there is no origin for it to cross — and a
|
|
10140
|
+
* target that does not parse is refused rather than trusted.
|
|
9628
10141
|
*
|
|
9629
10142
|
* @param target - The URL the request is about to go to.
|
|
9630
10143
|
* @param reference - The origin the credential belongs to, normally the
|
|
@@ -9920,7 +10433,7 @@ declare interface LayoutProps {
|
|
|
9920
10433
|
layout?: FormLayout;
|
|
9921
10434
|
/** Number of columns when `layout="grid"`, or a custom `grid-template-columns` value. Default `2`. */
|
|
9922
10435
|
columns?: number | string;
|
|
9923
|
-
/** Gap between fields. Numbers map to a multiple of the 4px scale (default `4` → 16px). */
|
|
10436
|
+
/** 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. */
|
|
9924
10437
|
gap?: number | string;
|
|
9925
10438
|
}
|
|
9926
10439
|
|
|
@@ -10320,6 +10833,64 @@ export declare interface LoggerSink {
|
|
|
10320
10833
|
(entry: LogEntry): void;
|
|
10321
10834
|
}
|
|
10322
10835
|
|
|
10836
|
+
/**
|
|
10837
|
+
* Default fields of `LoginForm`: e-mail and password.
|
|
10838
|
+
*
|
|
10839
|
+
* Exported, like the other presets' lists, so an app extends the defaults
|
|
10840
|
+
* (`[...LOGIN_FIELDS, { name: "remember", type: "checkbox", … }]`) instead of
|
|
10841
|
+
* retyping them.
|
|
10842
|
+
*/
|
|
10843
|
+
export declare const LOGIN_FIELDS: readonly AuthField<"email" | "password">[];
|
|
10844
|
+
|
|
10845
|
+
/**
|
|
10846
|
+
* Sign-in form: e-mail and password, "forgot password" link, sign-up line and a
|
|
10847
|
+
* slot for social buttons.
|
|
10848
|
+
*
|
|
10849
|
+
* `AuthForm` with the defaults every app wrote by hand: the e-mail trimmed and
|
|
10850
|
+
* lower-cased before validation, `current-password` autocomplete so the saved
|
|
10851
|
+
* password is offered, and the two links in the place users look for them. What
|
|
10852
|
+
* happens on success — storing the session, redirecting — stays in `onSubmit`.
|
|
10853
|
+
*
|
|
10854
|
+
* @example
|
|
10855
|
+
* <LoginForm
|
|
10856
|
+
* onSubmit={async (values) => { await auth.login(values); navigate("/"); }}
|
|
10857
|
+
* links={{ forgotPassword: "/recuperar-senha", signUp: "/cadastro" }}
|
|
10858
|
+
* social={<GoogleSignIn component={GoogleLogin} onSuccess={signInWithGoogle} />}
|
|
10859
|
+
* />
|
|
10860
|
+
*/
|
|
10861
|
+
export declare function LoginForm<TSchema extends z.ZodTypeAny = typeof loginSchema>({ schema, fields, links, labels, submitLabel, ...props }: LoginFormProps<TSchema>): ReactNode;
|
|
10862
|
+
|
|
10863
|
+
/** Sentences of {@link LoginForm}, PT-BR by default. */
|
|
10864
|
+
export declare interface LoginFormLabels extends AuthFormLabels {
|
|
10865
|
+
/** Default `"Esqueceu a senha?"`. */
|
|
10866
|
+
forgotPassword: string;
|
|
10867
|
+
/** Default `"Não tem uma conta?"`. */
|
|
10868
|
+
signUpPrompt: string;
|
|
10869
|
+
/** Default `"Cadastre-se"`. */
|
|
10870
|
+
signUp: string;
|
|
10871
|
+
}
|
|
10872
|
+
|
|
10873
|
+
/** Routes the login form links to. Each link is rendered only when its route is set. */
|
|
10874
|
+
export declare interface LoginFormLinks {
|
|
10875
|
+
/** "Esqueceu a senha?" link, above the submit button. */
|
|
10876
|
+
forgotPassword?: string;
|
|
10877
|
+
/** "Cadastre-se" link, under the form. */
|
|
10878
|
+
signUp?: string;
|
|
10879
|
+
}
|
|
10880
|
+
|
|
10881
|
+
export declare interface LoginFormProps<TSchema extends z.ZodTypeAny = typeof loginSchema> extends AuthPresetProps<TSchema> {
|
|
10882
|
+
/** Where the links go. */
|
|
10883
|
+
links?: LoginFormLinks;
|
|
10884
|
+
/** Overrides for the fixed sentences. */
|
|
10885
|
+
labels?: Partial<LoginFormLabels>;
|
|
10886
|
+
}
|
|
10887
|
+
|
|
10888
|
+
/** Default schema of `LoginForm`: normalized e-mail + password of at least 8 characters. */
|
|
10889
|
+
export declare const loginSchema: z.ZodObject<{
|
|
10890
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
10891
|
+
password: z.ZodString;
|
|
10892
|
+
}, z.core.$strip>;
|
|
10893
|
+
|
|
10323
10894
|
export declare type LogLevel = "debug" | "info" | "warn" | "error";
|
|
10324
10895
|
|
|
10325
10896
|
/**
|
|
@@ -11193,7 +11764,12 @@ export declare function NavigationMenu({ items, portal, className, ...props }: N
|
|
|
11193
11764
|
export declare interface NavigationMenuItem {
|
|
11194
11765
|
/** Visible label for the entry. */
|
|
11195
11766
|
label: ReactNode;
|
|
11196
|
-
/**
|
|
11767
|
+
/**
|
|
11768
|
+
* When set, the entry renders as an anchor. The URL is checked against
|
|
11769
|
+
* `safeLinkUrl`'s allowlist: a scheme outside `http:`/`https:`/`mailto:`/`tel:`/`sms:`
|
|
11770
|
+
* renders the entry as a button instead, so a menu built from API data cannot
|
|
11771
|
+
* put a clickable `javascript:` link on the page under React 18.
|
|
11772
|
+
*/
|
|
11197
11773
|
href?: string;
|
|
11198
11774
|
/** Invoked when the entry is activated (click / Enter). */
|
|
11199
11775
|
onSelect?: () => void;
|
|
@@ -11565,7 +12141,8 @@ export declare interface OfflineQueryPersistence {
|
|
|
11565
12141
|
/**
|
|
11566
12142
|
* Load the persisted snapshot into the `QueryClient`. Call once on boot,
|
|
11567
12143
|
* before rendering queries, so cached data is available offline. A no-op
|
|
11568
|
-
* once {@link OfflineQueryPersistence.clear} has been called
|
|
12144
|
+
* once {@link OfflineQueryPersistence.clear} has been called, and — with
|
|
12145
|
+
* `getPrincipal` — for a snapshot written under another principal.
|
|
11569
12146
|
*/
|
|
11570
12147
|
restore: () => Promise<void>;
|
|
11571
12148
|
/**
|
|
@@ -11625,6 +12202,29 @@ export declare interface OfflineQueryPersistenceOptions {
|
|
|
11625
12202
|
* one trailing write per window. Default `1000`.
|
|
11626
12203
|
*/
|
|
11627
12204
|
throttleMs?: number;
|
|
12205
|
+
/**
|
|
12206
|
+
* Who is signed in right now — a stable, non-secret id such as the user id;
|
|
12207
|
+
* `null`/`undefined` when nobody is. Read on every write, which stamps the
|
|
12208
|
+
* snapshot with a one-way fingerprint of it (never the id itself), and on
|
|
12209
|
+
* `restore()`, which hydrates only a snapshot stamped with the same
|
|
12210
|
+
* fingerprint.
|
|
12211
|
+
*
|
|
12212
|
+
* `clear()` on logout already deletes the snapshot; this covers the session
|
|
12213
|
+
* that ends without it — a token that expired, a crash, a tab closed while
|
|
12214
|
+
* signed in. Without it, the next account to boot on the browser is shown
|
|
12215
|
+
* the previous account's cached responses (#531). A snapshot written before
|
|
12216
|
+
* this option was set carries no stamp and is not restored either; it is a
|
|
12217
|
+
* cache, so the cost is one cold start.
|
|
12218
|
+
*
|
|
12219
|
+
* A foreign snapshot is skipped, not deleted: a cookie app that only learns
|
|
12220
|
+
* the principal after a `/me` round trip would otherwise wipe its own cache
|
|
12221
|
+
* on every cold start. The next write replaces it.
|
|
12222
|
+
*
|
|
12223
|
+
* Read synchronously. A non-string, non-number value (the `Promise` of an
|
|
12224
|
+
* `async` getter) or a getter that throws reads as nobody. Omit it to restore
|
|
12225
|
+
* every snapshot, as before 0.82.0.
|
|
12226
|
+
*/
|
|
12227
|
+
getPrincipal?: () => string | number | null | undefined;
|
|
11628
12228
|
}
|
|
11629
12229
|
|
|
11630
12230
|
/** Maps each table name to the record type it stores. */
|
|
@@ -11703,9 +12303,22 @@ export declare interface OfflineSync<TPayload> {
|
|
|
11703
12303
|
pendingCount: () => Promise<number>;
|
|
11704
12304
|
/** The queued mutations in FIFO order. */
|
|
11705
12305
|
listPending: () => Promise<OutboxEntry<TPayload>[]>;
|
|
11706
|
-
/**
|
|
12306
|
+
/**
|
|
12307
|
+
* Drop every queued mutation (e.g. on logout).
|
|
12308
|
+
*
|
|
12309
|
+
* Also ends the current session for any `flush` already in flight: that run
|
|
12310
|
+
* delivers no further entry, pulls and applies nothing more and writes no
|
|
12311
|
+
* watermark, and resolves with `interrupted: true`. A `flush` called after this
|
|
12312
|
+
* starts a fresh run instead of joining the abandoned one.
|
|
12313
|
+
*/
|
|
11707
12314
|
clearOutbox: () => Promise<void>;
|
|
11708
|
-
/**
|
|
12315
|
+
/**
|
|
12316
|
+
* Reset the pull watermark (e.g. on logout / account switch).
|
|
12317
|
+
*
|
|
12318
|
+
* Ends the current session for an in-flight `flush` exactly like
|
|
12319
|
+
* {@link OfflineSync.clearOutbox}, so the run cannot write the ended
|
|
12320
|
+
* session's watermark back after the reset.
|
|
12321
|
+
*/
|
|
11709
12322
|
resetWatermark: () => void;
|
|
11710
12323
|
/** Read the current reactive {@link SyncState} snapshot synchronously. */
|
|
11711
12324
|
getState: () => SyncState;
|
|
@@ -11788,6 +12401,30 @@ export declare interface OfflineSyncConfig<TPayload, TRemote> {
|
|
|
11788
12401
|
crossTab?: boolean;
|
|
11789
12402
|
/** Channel name when `crossTab` is on. Default `tempest-sync:${databaseName}`. */
|
|
11790
12403
|
broadcastChannelName?: string;
|
|
12404
|
+
/**
|
|
12405
|
+
* Who is signed in right now — a stable, non-secret id such as the user id;
|
|
12406
|
+
* `null`/`undefined` when nobody is. Read synchronously when an entry is
|
|
12407
|
+
* queued, which stamps it with a one-way fingerprint (`entry.owner`, never
|
|
12408
|
+
* the id itself), and again right before each delivery:
|
|
12409
|
+
*
|
|
12410
|
+
* - same principal → delivered;
|
|
12411
|
+
* - nobody signed in now → held: it stays queued and goes out when its owner
|
|
12412
|
+
* signs back in, so a flush fired by the `online` event before login loses
|
|
12413
|
+
* nothing;
|
|
12414
|
+
* - anybody else → deleted unsent and counted in `summary.dropped`, because
|
|
12415
|
+
* delivering it would send the previous account's mutation with the next
|
|
12416
|
+
* account's session.
|
|
12417
|
+
*
|
|
12418
|
+
* `clearOutbox()` on logout already empties the queue; this covers the app
|
|
12419
|
+
* that forgets it, or a session that ends without a logout (#531). Entries
|
|
12420
|
+
* queued before this option was set carry no stamp and are delivered as
|
|
12421
|
+
* before — they are the user's own unsynced edits, and holding them would
|
|
12422
|
+
* strand every queue on upgrade.
|
|
12423
|
+
*
|
|
12424
|
+
* A non-string, non-number value (the `Promise` of an `async` getter) or a
|
|
12425
|
+
* getter that throws reads as nobody. Default: no owner binding.
|
|
12426
|
+
*/
|
|
12427
|
+
getPrincipal?: () => string | number | null | undefined;
|
|
11791
12428
|
}
|
|
11792
12429
|
|
|
11793
12430
|
export declare interface OfflineTableConfig<TItem> {
|
|
@@ -12069,6 +12706,13 @@ export declare interface OutboxEntry<TPayload = unknown> {
|
|
|
12069
12706
|
lastError?: string;
|
|
12070
12707
|
/** Record snapshot for `create`/`update`. Omitted for `delete`. */
|
|
12071
12708
|
payload?: TPayload;
|
|
12709
|
+
/**
|
|
12710
|
+
* One-way fingerprint of whoever was signed in when the entry was queued
|
|
12711
|
+
* (`null` for nobody), stamped only when the engine has
|
|
12712
|
+
* {@link OfflineSyncConfig.getPrincipal}. Absent on entries queued without
|
|
12713
|
+
* it, which are delivered as before.
|
|
12714
|
+
*/
|
|
12715
|
+
owner?: string | null;
|
|
12072
12716
|
}
|
|
12073
12717
|
|
|
12074
12718
|
/**
|
|
@@ -12635,6 +13279,23 @@ export declare interface PeerMeshOptions {
|
|
|
12635
13279
|
onState?: (state: MeshState, detail?: string) => void;
|
|
12636
13280
|
/** Called for a failure worth surfacing that is not fatal to the mesh. */
|
|
12637
13281
|
onNotice?: (reason: string) => void;
|
|
13282
|
+
/**
|
|
13283
|
+
* Decide whether an offer from a peer the mesh has no link to is answered.
|
|
13284
|
+
*
|
|
13285
|
+
* By default the mesh answers any offer that reaches {@link PeerMesh.accept},
|
|
13286
|
+
* opening a link and publishing the local tracks to it — the answering side
|
|
13287
|
+
* usually learns of a peer from its offer, so that is the documented flow.
|
|
13288
|
+
* It also means whether the microphone and camera reach someone rests only
|
|
13289
|
+
* on the signalling server relaying offers to the right people. Pass a gate
|
|
13290
|
+
* — typically "is this user in the room roster I fetched" — to make that
|
|
13291
|
+
* the app's decision too. A refused offer opens nothing, answers nothing and
|
|
13292
|
+
* reports `onNotice("offer_refused")`. Peers added with `addPeer` are not
|
|
13293
|
+
* asked: adding them was the decision.
|
|
13294
|
+
*
|
|
13295
|
+
* @param peerId - The `from` of the offer.
|
|
13296
|
+
* @returns `true` to answer it.
|
|
13297
|
+
*/
|
|
13298
|
+
acceptPeer?: (peerId: string) => boolean;
|
|
12638
13299
|
/** Initial encoder limits. */
|
|
12639
13300
|
quality?: MeshQuality;
|
|
12640
13301
|
/** Measure every link, on one timer the mesh owns. See {@link MeshStatsOptions}. */
|
|
@@ -13105,13 +13766,25 @@ export declare function projectMercator(coord: Coordinate): MercatorPoint;
|
|
|
13105
13766
|
* keeps an entry pending when one it stripped is missing), or `null` when there
|
|
13106
13767
|
* is no session — the worker then drops the entry instead of replaying it
|
|
13107
13768
|
* anonymously. A throw from `getHeaders` or `getPrincipal` is answered as an
|
|
13108
|
-
* explicit `{ error: true }`.
|
|
13109
|
-
*
|
|
13110
|
-
*
|
|
13769
|
+
* explicit `{ error: true }`.
|
|
13770
|
+
*
|
|
13771
|
+
* The worker applies only the header names the original request carried, and
|
|
13772
|
+
* only to the worker's own origin or the `trustedOrigins` given to
|
|
13773
|
+
* {@link installBackgroundSync}: an entry bound for any other origin is dropped
|
|
13774
|
+
* without asking this page. Matching the name is not enough on its own — a
|
|
13775
|
+
* request to a third party carries *that party's* `Authorization`, and until
|
|
13776
|
+
* 0.81.0 its replay received the app's bearer (#523). `getHeaders` still gets
|
|
13777
|
+
* the URL, for an app whose trusted origins need different credentials.
|
|
13111
13778
|
*
|
|
13112
13779
|
* Pass `getPrincipal` to bind each entry to whoever queued it: the worker asks
|
|
13113
13780
|
* the issuing tab right after queueing, asks every tab again before replaying,
|
|
13114
|
-
* and drops the entry when no signed-in tab is its owner.
|
|
13781
|
+
* and drops the entry when no signed-in tab is its owner. Without it every
|
|
13782
|
+
* entry is `"unbound"` and replays with whichever session answers — the next
|
|
13783
|
+
* account's bearer included, unless `clearSessionData()` ran on logout — so a
|
|
13784
|
+
* development build warns once per call (#531). Treating an unbound
|
|
13785
|
+
* credentialed entry as `"unknown"` instead would change nothing: an
|
|
13786
|
+
* `"unknown"` entry replays when no answering tab reports a principal, which is
|
|
13787
|
+
* exactly the page that omits `getPrincipal`.
|
|
13115
13788
|
*
|
|
13116
13789
|
* @param getHeaders - Resolves the headers for one queued request at replay.
|
|
13117
13790
|
* @param options - `getPrincipal` binds entries to their owner.
|
|
@@ -13233,7 +13906,14 @@ export declare interface PushPayload {
|
|
|
13233
13906
|
dir?: NotificationDirection;
|
|
13234
13907
|
/** BCP 47 language tag of the title and body. */
|
|
13235
13908
|
lang?: string;
|
|
13236
|
-
/**
|
|
13909
|
+
/**
|
|
13910
|
+
* Arbitrary extra data forwarded to `event.notification.data`.
|
|
13911
|
+
*
|
|
13912
|
+
* Its `url` and `actionUrls` keys are overwritten by the top-level `url` and
|
|
13913
|
+
* the actions' `url`s: those two keys decide where a click goes, and a
|
|
13914
|
+
* free-form bag — often filled from the record that triggered the push — must
|
|
13915
|
+
* not be able to redirect it.
|
|
13916
|
+
*/
|
|
13237
13917
|
data?: Record<string, unknown>;
|
|
13238
13918
|
}
|
|
13239
13919
|
|
|
@@ -13957,6 +14637,68 @@ export declare interface RequestOptions extends Omit<RequestInit, "body"> {
|
|
|
13957
14637
|
*/
|
|
13958
14638
|
export declare function requestPersistentStorage(): Promise<boolean>;
|
|
13959
14639
|
|
|
14640
|
+
/** Default fields of `ResetPasswordForm`: new password (with strength meter) and confirmation. */
|
|
14641
|
+
export declare const RESET_PASSWORD_FIELDS: readonly AuthField<"password" | "confirmPassword">[];
|
|
14642
|
+
|
|
14643
|
+
/**
|
|
14644
|
+
* "Choose a new password" form: password and confirmation, with the mismatch
|
|
14645
|
+
* reported under the confirmation field.
|
|
14646
|
+
*
|
|
14647
|
+
* The reset token stays out of the fields: it comes from the URL, and the app
|
|
14648
|
+
* adds it in `onSubmit` — `{ ...values, token }` — where it also decides what an
|
|
14649
|
+
* expired token looks like.
|
|
14650
|
+
*
|
|
14651
|
+
* @example
|
|
14652
|
+
* const [params] = useSearchParams();
|
|
14653
|
+
* <ResetPasswordForm
|
|
14654
|
+
* hints={["Pelo menos 8 caracteres"]}
|
|
14655
|
+
* onSubmit={async (values) => {
|
|
14656
|
+
* await api.post("/auth/reset-password", { body: { ...values, token: params.get("token") } });
|
|
14657
|
+
* }}
|
|
14658
|
+
* />
|
|
14659
|
+
*/
|
|
14660
|
+
export declare function ResetPasswordForm<TSchema extends z.ZodTypeAny = typeof resetPasswordSchema>({ schema, fields, hints, links, labels, submitLabel, ...props }: ResetPasswordFormProps<TSchema>): ReactNode;
|
|
14661
|
+
|
|
14662
|
+
/** Sentences of {@link ResetPasswordForm}, PT-BR by default. */
|
|
14663
|
+
export declare interface ResetPasswordFormLabels extends AuthFormLabels {
|
|
14664
|
+
/** Default `"Lembrou a senha?"`. */
|
|
14665
|
+
signInPrompt: string;
|
|
14666
|
+
/** Default `"Entrar"`. */
|
|
14667
|
+
signIn: string;
|
|
14668
|
+
/** Accessible name of the hints list. Default `"Requisitos da senha"`. */
|
|
14669
|
+
hints: string;
|
|
14670
|
+
}
|
|
14671
|
+
|
|
14672
|
+
/** Routes the reset-password form links to. */
|
|
14673
|
+
export declare interface ResetPasswordFormLinks {
|
|
14674
|
+
/** "Entrar" link, under the form. */
|
|
14675
|
+
signIn?: string;
|
|
14676
|
+
}
|
|
14677
|
+
|
|
14678
|
+
export declare interface ResetPasswordFormProps<TSchema extends z.ZodTypeAny = typeof resetPasswordSchema> extends AuthPresetProps<TSchema> {
|
|
14679
|
+
/**
|
|
14680
|
+
* Password requirements listed above the submit button ("Pelo menos 8
|
|
14681
|
+
* caracteres", "Uma letra maiúscula"). Kept as text the app writes, because
|
|
14682
|
+
* only the backend knows its rules.
|
|
14683
|
+
*/
|
|
14684
|
+
hints?: ReactNode[];
|
|
14685
|
+
/** Where the links go. */
|
|
14686
|
+
links?: ResetPasswordFormLinks;
|
|
14687
|
+
/** Overrides for the fixed sentences. */
|
|
14688
|
+
labels?: Partial<ResetPasswordFormLabels>;
|
|
14689
|
+
}
|
|
14690
|
+
|
|
14691
|
+
/**
|
|
14692
|
+
* Default schema of `ResetPasswordForm`: new password and its confirmation.
|
|
14693
|
+
*
|
|
14694
|
+
* The mismatch is reported on `confirmPassword` (`path`), so the message lands
|
|
14695
|
+
* under the field the user has to fix rather than in a form-level alert.
|
|
14696
|
+
*/
|
|
14697
|
+
export declare const resetPasswordSchema: z.ZodObject<{
|
|
14698
|
+
password: z.ZodString;
|
|
14699
|
+
confirmPassword: z.ZodString;
|
|
14700
|
+
}, z.core.$strip>;
|
|
14701
|
+
|
|
13960
14702
|
/**
|
|
13961
14703
|
* A two-pane split layout with a draggable divider. The first pane is sized via
|
|
13962
14704
|
* `flex-basis` as a percentage; the second pane fills the rest. Drag the divider
|
|
@@ -14088,7 +14830,11 @@ export declare interface ResumableUploadOptions {
|
|
|
14088
14830
|
chunkSize?: number;
|
|
14089
14831
|
/** Sent as `Upload-Metadata` (base64-encoded values), e.g. `{ filename }`. */
|
|
14090
14832
|
metadata?: Record<string, string>;
|
|
14091
|
-
/**
|
|
14833
|
+
/**
|
|
14834
|
+
* Extra headers on every request inside the credential scope — the
|
|
14835
|
+
* `endpoint`'s origin plus {@link trustedOrigins}. A `Location` on another
|
|
14836
|
+
* host gets only the tus headers, never these (since 0.82.0).
|
|
14837
|
+
*/
|
|
14092
14838
|
headers?: Record<string, string>;
|
|
14093
14839
|
/** Returns the current bearer token, read before each request. */
|
|
14094
14840
|
getToken?: () => string | null | undefined;
|
|
@@ -14100,13 +14846,20 @@ export declare interface ResumableUploadOptions {
|
|
|
14100
14846
|
* The resume record is stamped with a one-way fingerprint of it, and a
|
|
14101
14847
|
* record stamped by anyone else — another user, nobody, or no stamp at all
|
|
14102
14848
|
* — is deleted instead of resumed: its upload URL is not probed, and its
|
|
14103
|
-
* `Idempotency-Key` is never replayed.
|
|
14104
|
-
*
|
|
14105
|
-
*
|
|
14106
|
-
*
|
|
14107
|
-
*
|
|
14108
|
-
*
|
|
14109
|
-
*
|
|
14849
|
+
* `Idempotency-Key` is never replayed (#479).
|
|
14850
|
+
*
|
|
14851
|
+
* Without it, since 0.82.0 the record is bound to a fingerprint of the
|
|
14852
|
+
* `getToken` token instead, so another account's record is still never
|
|
14853
|
+
* adopted (#528) — but a token rotates: a reload after a refresh that no
|
|
14854
|
+
* chunk landed under starts the upload over. Pass `getPrincipal` to keep
|
|
14855
|
+
* resuming across refreshes, and always with a cookie session, where there
|
|
14856
|
+
* is no token to bind to and the record stays unbound.
|
|
14857
|
+
*
|
|
14858
|
+
* `getToken: auth.getToken` — the getter of `createTempestAuth` itself, not
|
|
14859
|
+
* an arrow around it — binds to that preset's session instead, as if
|
|
14860
|
+
* `getPrincipal: auth.sessionKey` were passed: the record survives token
|
|
14861
|
+
* rotation, a switch of account stops the run, and a new `login()`, even
|
|
14862
|
+
* into the same account, starts over.
|
|
14110
14863
|
*
|
|
14111
14864
|
* It is read again before every chunk and every record write: when it
|
|
14112
14865
|
* names someone else mid-run, the run stops with
|
|
@@ -14183,10 +14936,11 @@ export declare interface ResumableUploadRecord {
|
|
|
14183
14936
|
/** Epoch ms of the last write, so an app can sweep stale records. */
|
|
14184
14937
|
updatedAt: number;
|
|
14185
14938
|
/**
|
|
14186
|
-
* One-way fingerprint of the principal that created the upload (`"p:<hex>"`)
|
|
14187
|
-
*
|
|
14188
|
-
*
|
|
14189
|
-
*
|
|
14939
|
+
* One-way fingerprint of the principal that created the upload (`"p:<hex>"`)
|
|
14940
|
+
* or, without {@link ResumableUploadOptions.getPrincipal}, of the bearer
|
|
14941
|
+
* token of its last write (`"t:<hex>"`, since 0.82.0); `null` for an
|
|
14942
|
+
* anonymous one. Absent when the upload ran with neither getter, and on
|
|
14943
|
+
* records written before 0.78.0.
|
|
14190
14944
|
*/
|
|
14191
14945
|
owner?: string | null;
|
|
14192
14946
|
}
|
|
@@ -14507,8 +15261,9 @@ export declare interface RuntimeRoute {
|
|
|
14507
15261
|
*/
|
|
14508
15262
|
rangeRequests?: boolean;
|
|
14509
15263
|
/**
|
|
14510
|
-
* Opt in to caching requests that carry a credential
|
|
14511
|
-
* `credentialHeaders`)
|
|
15264
|
+
* Opt in to caching credentialed requests — those that carry a credential
|
|
15265
|
+
* header (see `credentialHeaders`) or are a CORS-mode `fetch` sent with
|
|
15266
|
+
* `credentials: "include"` — and responses marked `Cache-Control: private`.
|
|
14512
15267
|
* Default `false`.
|
|
14513
15268
|
*
|
|
14514
15269
|
* Cache Storage is keyed by URL and outlives the session: without this
|
|
@@ -14525,11 +15280,18 @@ export declare interface RuntimeRoute {
|
|
|
14525
15280
|
* `clearSessionData()` on logout, which removes the entries themselves.
|
|
14526
15281
|
* `Cache-Control: no-store` is never cached, opt-in or not.
|
|
14527
15282
|
*
|
|
14528
|
-
* A cookie session is
|
|
14529
|
-
*
|
|
14530
|
-
*
|
|
15283
|
+
* A cookie session is only partly visible here: the worker cannot see
|
|
15284
|
+
* `Cookie`. What it can see is a `fetch` that asked for cookies explicitly —
|
|
15285
|
+
* `mode: "cors"` with `credentials: "include"`, which is what `ApiClient`
|
|
15286
|
+
* sends under `withCredentials` — and since 0.82.0 that request is treated
|
|
15287
|
+
* as credentialed too (#531). `<img>`, `<audio>` and `<video>` also send
|
|
15288
|
+
* `credentials: "include"`, but in `no-cors` mode, so they keep caching. A
|
|
15289
|
+
* plain same-origin `fetch` (`credentials: "same-origin"`, the default)
|
|
15290
|
+
* carries the cookie without saying so; such an API stays private only
|
|
14531
15291
|
* through `Cache-Control: private`/`no-store` on its responses and
|
|
14532
|
-
* `clearSessionData()` on logout.
|
|
15292
|
+
* `clearSessionData()` on logout. Opting a cookie request in caches it by
|
|
15293
|
+
* URL — there is no credential header to vary on — so `clearSessionData()`
|
|
15294
|
+
* is then its only isolation.
|
|
14533
15295
|
*/
|
|
14534
15296
|
cacheAuthenticated?: boolean;
|
|
14535
15297
|
/**
|
|
@@ -15153,6 +15915,16 @@ export declare interface SequentialScaleOptions {
|
|
|
15153
15915
|
ordinal?: boolean;
|
|
15154
15916
|
}
|
|
15155
15917
|
|
|
15918
|
+
/**
|
|
15919
|
+
* Identifies the session a stream belongs to: the signed-in user's id, an
|
|
15920
|
+
* auth epoch, `null` when signed out.
|
|
15921
|
+
*
|
|
15922
|
+
* A primitive on purpose. The hook form lists it in its effect dependencies,
|
|
15923
|
+
* and an object built inline would be a new identity on every render, so the
|
|
15924
|
+
* stream would reopen on every render.
|
|
15925
|
+
*/
|
|
15926
|
+
export declare type SessionKey = string | number | boolean | null | undefined;
|
|
15927
|
+
|
|
15156
15928
|
/**
|
|
15157
15929
|
* Thrown when the session that started an operation is no longer the current
|
|
15158
15930
|
* one by the time it settles: a `refresh` hook (rethrown by
|
|
@@ -15534,6 +16306,10 @@ export declare interface SidebarItem {
|
|
|
15534
16306
|
* A `disabled` entry ignores this and stays a `<button disabled>`: there is no
|
|
15535
16307
|
* disabled state for an anchor, and dropping the `href` to fake one leaves a
|
|
15536
16308
|
* link that announces itself as actionable and is not.
|
|
16309
|
+
*
|
|
16310
|
+
* The URL goes through `safeLinkUrl`: a scheme outside
|
|
16311
|
+
* `http:`/`https:`/`mailto:`/`tel:`/`sms:` makes the entry a button, the same
|
|
16312
|
+
* as an entry without `href`.
|
|
15537
16313
|
*/
|
|
15538
16314
|
href?: string;
|
|
15539
16315
|
}
|
|
@@ -15593,6 +16369,9 @@ export declare interface SidebarSeparator {
|
|
|
15593
16369
|
key: string;
|
|
15594
16370
|
}
|
|
15595
16371
|
|
|
16372
|
+
/** Default fields of `SignUpForm`: name, e-mail and a password with strength meter. */
|
|
16373
|
+
export declare const SIGN_UP_FIELDS: readonly AuthField<"name" | "email" | "password">[];
|
|
16374
|
+
|
|
15596
16375
|
/**
|
|
15597
16376
|
* Signature capture on a canvas — the "sign here" field of a delivery receipt,
|
|
15598
16377
|
* a service order, a term of acceptance.
|
|
@@ -15664,6 +16443,59 @@ export declare interface SignaturePadProps {
|
|
|
15664
16443
|
className?: string;
|
|
15665
16444
|
}
|
|
15666
16445
|
|
|
16446
|
+
/**
|
|
16447
|
+
* Sign-up form: name, e-mail and password by default, plus the "Já tem uma conta?"
|
|
16448
|
+
* line.
|
|
16449
|
+
*
|
|
16450
|
+
* Apps differ most here — a phone, a CPF, a terms checkbox — so the usual call
|
|
16451
|
+
* passes `fields` and a `schema` built with `signUpSchema.extend({...})`. The
|
|
16452
|
+
* password defaults to `new-password` autocomplete, which is what makes a
|
|
16453
|
+
* password manager offer to generate one.
|
|
16454
|
+
*
|
|
16455
|
+
* @example
|
|
16456
|
+
* <SignUpForm
|
|
16457
|
+
* schema={signUpSchema.extend({ terms: z.literal(true, "Aceite os termos") })}
|
|
16458
|
+
* fields={[...SIGN_UP_FIELDS, { name: "terms", type: "checkbox", label: "Aceito os termos" }]}
|
|
16459
|
+
* onSubmit={async (values) => { await api.post("/auth/register", { body: values }); }}
|
|
16460
|
+
* links={{ signIn: "/login" }}
|
|
16461
|
+
* />
|
|
16462
|
+
*/
|
|
16463
|
+
export declare function SignUpForm<TSchema extends z.ZodTypeAny = typeof signUpSchema>({ schema, fields, links, labels, submitLabel, ...props }: SignUpFormProps<TSchema>): ReactNode;
|
|
16464
|
+
|
|
16465
|
+
/** Sentences of {@link SignUpForm}, PT-BR by default. */
|
|
16466
|
+
export declare interface SignUpFormLabels extends AuthFormLabels {
|
|
16467
|
+
/** Default `"Já tem uma conta?"`. */
|
|
16468
|
+
signInPrompt: string;
|
|
16469
|
+
/** Default `"Entrar"`. */
|
|
16470
|
+
signIn: string;
|
|
16471
|
+
}
|
|
16472
|
+
|
|
16473
|
+
/** Routes the sign-up form links to. */
|
|
16474
|
+
export declare interface SignUpFormLinks {
|
|
16475
|
+
/** "Entrar" link, under the form. */
|
|
16476
|
+
signIn?: string;
|
|
16477
|
+
}
|
|
16478
|
+
|
|
16479
|
+
export declare interface SignUpFormProps<TSchema extends z.ZodTypeAny = typeof signUpSchema> extends AuthPresetProps<TSchema> {
|
|
16480
|
+
/** Where the links go. */
|
|
16481
|
+
links?: SignUpFormLinks;
|
|
16482
|
+
/** Overrides for the fixed sentences. */
|
|
16483
|
+
labels?: Partial<SignUpFormLabels>;
|
|
16484
|
+
}
|
|
16485
|
+
|
|
16486
|
+
/**
|
|
16487
|
+
* Default schema of `SignUpForm`: name, e-mail and password.
|
|
16488
|
+
*
|
|
16489
|
+
* Exported so an app adds its own fields with `.extend()` instead of rewriting
|
|
16490
|
+
* the three it shares with every other app — see the phone and terms example in
|
|
16491
|
+
* the docs.
|
|
16492
|
+
*/
|
|
16493
|
+
export declare const signUpSchema: z.ZodObject<{
|
|
16494
|
+
name: z.ZodString;
|
|
16495
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
16496
|
+
password: z.ZodString;
|
|
16497
|
+
}, z.core.$strip>;
|
|
16498
|
+
|
|
15667
16499
|
/** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
|
|
15668
16500
|
export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
|
|
15669
16501
|
|
|
@@ -15958,7 +16790,7 @@ export declare type StackJustify = "start" | "center" | "end" | "between";
|
|
|
15958
16790
|
export declare interface StackProps extends HTMLAttributes<HTMLDivElement> {
|
|
15959
16791
|
/** Direction. Accepts responsive object — e.g. `{ mobile: "vertical", desktop: "horizontal" }`. */
|
|
15960
16792
|
direction?: ResponsiveValue<StackDirection>;
|
|
15961
|
-
/** Gap as a CSS length. Numbers map to a multiple of the 4px scale. Accepts responsive object. */
|
|
16793
|
+
/** 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. */
|
|
15962
16794
|
gap?: ResponsiveValue<number | string>;
|
|
15963
16795
|
align?: StackAlign;
|
|
15964
16796
|
justify?: StackJustify;
|
|
@@ -16169,6 +17001,27 @@ export declare interface SyncRunSummary {
|
|
|
16169
17001
|
skipped: boolean;
|
|
16170
17002
|
/** Last delivery error message seen this run, or `null` when none failed. */
|
|
16171
17003
|
lastError: string | null;
|
|
17004
|
+
/**
|
|
17005
|
+
* `true` when {@link OfflineSync.clearOutbox} or {@link OfflineSync.resetWatermark}
|
|
17006
|
+
* ended the session while this run was in flight, so it stopped early.
|
|
17007
|
+
*
|
|
17008
|
+
* The counts cover only what happened before the stop: a delivery already in
|
|
17009
|
+
* progress at logout is still counted, but no later entry was sent, no further
|
|
17010
|
+
* page was pulled or applied, and the watermark was not written. Absent on a
|
|
17011
|
+
* run that went to completion.
|
|
17012
|
+
*/
|
|
17013
|
+
interrupted?: true;
|
|
17014
|
+
/**
|
|
17015
|
+
* Entries left queued because nobody is signed in and they belong to
|
|
17016
|
+
* somebody (see {@link OfflineSyncConfig.getPrincipal}). Absent when zero.
|
|
17017
|
+
*/
|
|
17018
|
+
held?: number;
|
|
17019
|
+
/**
|
|
17020
|
+
* Entries deleted unsent because they were queued under another principal —
|
|
17021
|
+
* or while signed out — and somebody else is signed in now (see
|
|
17022
|
+
* {@link OfflineSyncConfig.getPrincipal}). Absent when zero.
|
|
17023
|
+
*/
|
|
17024
|
+
dropped?: number;
|
|
16172
17025
|
}
|
|
16173
17026
|
|
|
16174
17027
|
/**
|
|
@@ -16462,6 +17315,34 @@ export declare interface TempestAuth<TUser, TCredentials> {
|
|
|
16462
17315
|
refresh: () => Promise<void>;
|
|
16463
17316
|
/** The current access token, or null. */
|
|
16464
17317
|
getToken: () => string | null;
|
|
17318
|
+
/**
|
|
17319
|
+
* The key of the session signed in now, or `null` when nobody is.
|
|
17320
|
+
*
|
|
17321
|
+
* It changes when the session is replaced — `login()`, even into the same
|
|
17322
|
+
* account, a sign-in or sign-out in another tab, `logout()` — and stays
|
|
17323
|
+
* the same while that session's tokens rotate: it is the session lineage
|
|
17324
|
+
* `login()` mints, not the token. That is the identity a per-session
|
|
17325
|
+
* resource needs. `useTicketEventStream`/`createTicketEventStream` read it
|
|
17326
|
+
* on their own from `api`, and `createResumableUpload` from `getToken`;
|
|
17327
|
+
* pass it as `sessionKey` or `getPrincipal` anywhere else.
|
|
17328
|
+
*
|
|
17329
|
+
* A session that has no lineage — persisted before lineages existed, or
|
|
17330
|
+
* restored from a refresh cookie without a `login()` in this storage —
|
|
17331
|
+
* answers `"unlineaged"`. Replacing it still takes a
|
|
17332
|
+
* `login()`, which mints one, so the key still changes on a switch.
|
|
17333
|
+
*/
|
|
17334
|
+
sessionKey: () => string | null;
|
|
17335
|
+
/**
|
|
17336
|
+
* Stop following the other tabs: removes the `storage` listener this
|
|
17337
|
+
* preset adds to `window`. Idempotent.
|
|
17338
|
+
*
|
|
17339
|
+
* An app keeps one preset for the page's lifetime and never needs it; it
|
|
17340
|
+
* exists for tests and hot-module reload, which build several presets in
|
|
17341
|
+
* one window. A disposed preset still compares the shared storage with
|
|
17342
|
+
* its session before every refresh, so it never redeems another tab's
|
|
17343
|
+
* refresh token.
|
|
17344
|
+
*/
|
|
17345
|
+
dispose: () => void;
|
|
16465
17346
|
}
|
|
16466
17347
|
|
|
16467
17348
|
/**
|
|
@@ -16558,6 +17439,22 @@ declare interface TempestSessionEnd<TUser> {
|
|
|
16558
17439
|
* call to fail and keep the local half of the teardown independent of it.
|
|
16559
17440
|
*/
|
|
16560
17441
|
api: ApiClient;
|
|
17442
|
+
/**
|
|
17443
|
+
* Whether another tab of the origin ended or replaced the session, and this
|
|
17444
|
+
* tab is only catching up (#524). With `storage: "local"` the session's
|
|
17445
|
+
* keys are shared by every tab, so a `logout()` or a `login()` in one tab
|
|
17446
|
+
* ends the session in all of them: `reason` is `"logout"` when the other
|
|
17447
|
+
* tab left no session behind and `"switch"` when it installed another
|
|
17448
|
+
* account.
|
|
17449
|
+
*
|
|
17450
|
+
* The other tab already ran this hook for the same session. Teardown that
|
|
17451
|
+
* lives in this tab's memory (an in-memory cache, an open socket) still has
|
|
17452
|
+
* to run here; teardown of state the origin shares (IndexedDB, Cache
|
|
17453
|
+
* Storage, a push subscription) was done there, and on `"switch"` redoing
|
|
17454
|
+
* it here would wipe what the new account already wrote — skip it when
|
|
17455
|
+
* this is `true`.
|
|
17456
|
+
*/
|
|
17457
|
+
elsewhere: boolean;
|
|
16561
17458
|
}
|
|
16562
17459
|
|
|
16563
17460
|
/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */
|
|
@@ -16609,6 +17506,10 @@ export declare function themeContrast(options: CreateThemeOptions): number | nul
|
|
|
16609
17506
|
* hydrates. Inline this in `<head>` to avoid a flash of the wrong theme on
|
|
16610
17507
|
* first paint.
|
|
16611
17508
|
*
|
|
17509
|
+
* Both options are embedded through an escaper that keeps them inside the
|
|
17510
|
+
* `<script>` element whatever they contain, so the snippet is safe to inline
|
|
17511
|
+
* even when the storage key comes from configuration.
|
|
17512
|
+
*
|
|
16612
17513
|
* @example
|
|
16613
17514
|
* <script dangerouslySetInnerHTML={{ __html: themeInitScript() }} />
|
|
16614
17515
|
*/
|
|
@@ -16704,6 +17605,10 @@ export declare interface TicketEventStreamSource {
|
|
|
16704
17605
|
* Authenticated client the ticket is requested through, so it carries the
|
|
16705
17606
|
* `Authorization` header or the session cookie, the CSRF header, and the
|
|
16706
17607
|
* 401 refresh-and-replay that a hand-rolled `fetch` would lose.
|
|
17608
|
+
*
|
|
17609
|
+
* The `api` of `createTempestAuth` also carries the session it acts for,
|
|
17610
|
+
* and the stream binds to it when `sessionKey` is not passed — see
|
|
17611
|
+
* {@link useTicketEventStream}.
|
|
16707
17612
|
*/
|
|
16708
17613
|
client: Pick<ApiClient, "post" | "url">;
|
|
16709
17614
|
/** Router prefix, relative to the client's base URL. Default: `"/sse"`. */
|
|
@@ -17509,7 +18414,12 @@ export declare function uploadFingerprint(endpoint: string, file: Blob | File):
|
|
|
17509
18414
|
* allowing a preflight.
|
|
17510
18415
|
*
|
|
17511
18416
|
* A file larger than `post.max_bytes` is refused before anything is sent, with
|
|
17512
|
-
* the same `413 FILE_TOO_LARGE` the server would answer.
|
|
18417
|
+
* the same `413 FILE_TOO_LARGE` the server would answer. A numeric string
|
|
18418
|
+
* (`"5242880"`) compares as a number; a missing or non-numeric `max_bytes` —
|
|
18419
|
+
* a bare boto3 `generate_presigned_post` has none — skips this precheck, and
|
|
18420
|
+
* the signed policy's `content-length-range` stays the control that refuses
|
|
18421
|
+
* the bytes. The precheck saves a wasted upload; it never was the limit.
|
|
18422
|
+
* Server errors are
|
|
17513
18423
|
* normalized into one `TempestApiError` whichever backend answered: the S3 XML
|
|
17514
18424
|
* (`EntityTooLarge` → `FILE_TOO_LARGE`, `EntityTooSmall` → `FILE_TOO_SMALL`,
|
|
17515
18425
|
* `AccessDenied` → `SIGNED_URL_INVALID`, or `SIGNED_URL_EXPIRED` when the policy
|
|
@@ -17566,18 +18476,22 @@ export declare interface UploadWithProgressOptions {
|
|
|
17566
18476
|
getToken?: () => string | null | undefined;
|
|
17567
18477
|
/**
|
|
17568
18478
|
* Origin the `getToken` credential belongs to, normally the API's.
|
|
18479
|
+
* Defaults to the page's own origin (`location.origin`).
|
|
17569
18480
|
*
|
|
17570
18481
|
* Unlike `createApiClient`, this helper has no base URL to infer a scope
|
|
17571
|
-
* from — the caller names the destination on every call
|
|
17572
|
-
*
|
|
17573
|
-
*
|
|
17574
|
-
*
|
|
17575
|
-
*
|
|
18482
|
+
* from — the caller names the destination on every call, and the `url` can
|
|
18483
|
+
* come from somewhere other than your own code (a signed URL the API handed
|
|
18484
|
+
* back, a value from a response body). Until 0.82.0 an unset scope sent the
|
|
18485
|
+
* token wherever `url` pointed; it now starts closed, like the CSRF token
|
|
18486
|
+
* always did, and an API on another origin sets this to receive it (#530).
|
|
18487
|
+
*
|
|
18488
|
+
* Outside a browsing context there is no page origin, and the scope falls
|
|
18489
|
+
* back to `url` itself.
|
|
17576
18490
|
*/
|
|
17577
18491
|
credentialOrigin?: string;
|
|
17578
18492
|
/**
|
|
17579
18493
|
* Extra origins allowed to receive the credential, on top of
|
|
17580
|
-
* {@link credentialOrigin}
|
|
18494
|
+
* {@link credentialOrigin} (or the page origin it defaults to).
|
|
17581
18495
|
*/
|
|
17582
18496
|
trustedOrigins?: readonly string[];
|
|
17583
18497
|
/** Send cookies. Defaults to false. */
|
|
@@ -17586,12 +18500,9 @@ export declare interface UploadWithProgressOptions {
|
|
|
17586
18500
|
* Send a CSRF token with the upload, as `createApiClient`'s `csrf` does.
|
|
17587
18501
|
* Off by default; `true` reads the `csrf_token` cookie into `X-CSRF-Token`.
|
|
17588
18502
|
*
|
|
17589
|
-
* Scoped
|
|
17590
|
-
*
|
|
17591
|
-
*
|
|
17592
|
-
* only for compatibility with every version before 0.66.0; this option is
|
|
17593
|
-
* new, so it starts closed. An API on another origin sets
|
|
17594
|
-
* `credentialOrigin` to receive the token.
|
|
18503
|
+
* Scoped exactly like the bearer token: to {@link credentialOrigin} (the
|
|
18504
|
+
* page's own origin when unset) plus {@link trustedOrigins}. An API on
|
|
18505
|
+
* another origin sets `credentialOrigin` to receive the token.
|
|
17595
18506
|
*/
|
|
17596
18507
|
csrf?: boolean | CsrfOptions;
|
|
17597
18508
|
/** Called on every `progress` event from the XHR upload channel. */
|
|
@@ -17972,9 +18883,19 @@ export declare function useBreakpoint(): BreakpointHelpers;
|
|
|
17972
18883
|
*
|
|
17973
18884
|
* Handles sync booleans, sync {@link CanResult}, and promises of either. When
|
|
17974
18885
|
* no provider is present, access is allowed (see `useAccessControl`). The check
|
|
17975
|
-
* re-runs whenever the params change
|
|
18886
|
+
* re-runs whenever the params change; they are compared by their
|
|
18887
|
+
* `JSON.stringify` form, so an inline object literal does not re-run it on
|
|
18888
|
+
* every render.
|
|
18889
|
+
*
|
|
18890
|
+
* A resolved answer is stored with the control and the params it answers, and
|
|
18891
|
+
* is only returned while both still match. Until 0.81.0 the previous answer was
|
|
18892
|
+
* returned with `isLoading: false` for the render between a params change and
|
|
18893
|
+
* the effect that re-ran the check, so `<Can>` showed the children for the new
|
|
18894
|
+
* resource for one frame on the strength of the old resource's permission. The
|
|
18895
|
+
* first render for new params now reads `{ allowed: false, isLoading: true }`.
|
|
17976
18896
|
*
|
|
17977
18897
|
* @param params - The action/resource being checked.
|
|
18898
|
+
* @returns The answer for exactly these params, or the pending state.
|
|
17978
18899
|
*/
|
|
17979
18900
|
export declare function useCan(params: CanParams): UseCanResult;
|
|
17980
18901
|
|
|
@@ -18314,8 +19235,12 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18314
19235
|
|
|
18315
19236
|
/**
|
|
18316
19237
|
* React hook wrapper around {@link createEventStream}. Connection lifecycle is
|
|
18317
|
-
* tied to the component (and the `url`/`enabled` dependencies);
|
|
18318
|
-
* closes on unmount.
|
|
19238
|
+
* tied to the component (and the `url`/`enabled`/`sessionKey` dependencies);
|
|
19239
|
+
* the stream closes on unmount.
|
|
19240
|
+
*
|
|
19241
|
+
* Pass `sessionKey` (the signed-in user's id) whenever the stream carries one
|
|
19242
|
+
* user's data: a change of account then closes the previous user's stream and
|
|
19243
|
+
* clears `lastMessage`, even when `enabled` never went `false` in between.
|
|
18319
19244
|
*
|
|
18320
19245
|
* A string `url` reopens the stream when it changes. A function `url` does not:
|
|
18321
19246
|
* an inline arrow is a new function every render, and keying on its identity
|
|
@@ -18347,9 +19272,24 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18347
19272
|
*/
|
|
18348
19273
|
export declare function useEventStream<T = unknown>(url: EventStreamUrl, options?: UseEventStreamOptions<T>): UseEventStreamResult<T>;
|
|
18349
19274
|
|
|
18350
|
-
export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange"> {
|
|
19275
|
+
export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange" | "sessionKey"> {
|
|
18351
19276
|
/** When false, the stream is not opened. Useful for "wait for auth". Default: true. */
|
|
18352
19277
|
enabled?: boolean;
|
|
19278
|
+
/**
|
|
19279
|
+
* The session the stream belongs to — the signed-in user's id, typically.
|
|
19280
|
+
*
|
|
19281
|
+
* A change closes the stream, clears `lastMessage` and, while `enabled`,
|
|
19282
|
+
* opens a new connection for the new session (a fresh ticket, for
|
|
19283
|
+
* {@link useTicketEventStream}). Without it, a tab that switches accounts
|
|
19284
|
+
* without passing through `enabled: false` keeps the previous user's
|
|
19285
|
+
* stream open and delivers its events under the new user: the server does
|
|
19286
|
+
* not end an open stream on logout or revocation, so the client has to.
|
|
19287
|
+
*
|
|
19288
|
+
* A frame that arrives between the render that changed the key and the
|
|
19289
|
+
* effect that closes the stream is dropped as well. Default: `undefined`,
|
|
19290
|
+
* which never changes, so the stream follows `url` and `enabled` alone.
|
|
19291
|
+
*/
|
|
19292
|
+
sessionKey?: SessionKey;
|
|
18353
19293
|
}
|
|
18354
19294
|
|
|
18355
19295
|
export declare interface UseEventStreamResult<T> {
|
|
@@ -20373,11 +21313,33 @@ export declare function useThrottle<T>(value: T, delay: number): T;
|
|
|
20373
21313
|
* Reopening on identity would reconnect on every render for a client built
|
|
20374
21314
|
* inline.
|
|
20375
21315
|
*
|
|
21316
|
+
* The stream is bound to a session: the ticket names the channel of the user
|
|
21317
|
+
* who asked for it, the server never ends an open stream on logout, and a tab
|
|
21318
|
+
* that switches accounts without `enabled` going `false` would otherwise keep
|
|
21319
|
+
* delivering the previous user's events. A change of session closes that
|
|
21320
|
+
* stream and asks a ticket for the new one.
|
|
21321
|
+
*
|
|
21322
|
+
* With the `api` of `createTempestAuth` as `client`, that binding is automatic
|
|
21323
|
+
* (since 0.82.0): the session is read from the client — `auth.sessionKey()`,
|
|
21324
|
+
* the lineage `login()` mints — so a switch closes the stream, a token
|
|
21325
|
+
* rotation of the same session does not, and while nobody is signed in the
|
|
21326
|
+
* stream stays `idle` without asking for a ticket. Any other client keeps the
|
|
21327
|
+
* behaviour it had: pass `sessionKey` (the signed-in user's id). A
|
|
21328
|
+
* `sessionKey` passed explicitly always wins over the client's.
|
|
21329
|
+
*
|
|
20376
21330
|
* @example
|
|
20377
21331
|
* const { status } = useTicketEventStream<Notification>({
|
|
21332
|
+
* client: auth.api,
|
|
21333
|
+
* schema: notificationSchema,
|
|
21334
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
21335
|
+
* });
|
|
21336
|
+
*
|
|
21337
|
+
* @example
|
|
21338
|
+
* // A client createTempestAuth did not build
|
|
21339
|
+
* const { status } = useTicketEventStream<Notification>({
|
|
20378
21340
|
* client: api,
|
|
20379
21341
|
* enabled: isAuthenticated,
|
|
20380
|
-
*
|
|
21342
|
+
* sessionKey: user?.id ?? null,
|
|
20381
21343
|
* onMessage: ({ data }) => addNotification(data),
|
|
20382
21344
|
* });
|
|
20383
21345
|
*
|
|
@@ -20599,7 +21561,7 @@ export { useWatch }
|
|
|
20599
21561
|
* for the host component and tears it down on unmount.
|
|
20600
21562
|
*
|
|
20601
21563
|
* Every callback is read through a ref, so `onOpen` / `onMessage` / `onClose` /
|
|
20602
|
-
* `onError` / `onReconnecting` / `onReconnected` / `onLost` always run the
|
|
21564
|
+
* `onError` / `onReconnecting` / `onReconnected` / `onLost` / `getPrincipal` always run the
|
|
20603
21565
|
* latest closure — an inline arrow function is fine and never reopens the
|
|
20604
21566
|
* socket. Connection-shaping options (`protocols`, `maxRetries`,
|
|
20605
21567
|
* `initialBackoff`, `maxBackoff`, `jitter`, `handshakeTimeout`,
|
|
@@ -20690,6 +21652,12 @@ export declare function validateCPF(value: string): boolean;
|
|
|
20690
21652
|
* become `"address.city"`, array entries `"items.0.name"`. The first issue
|
|
20691
21653
|
* per path wins (subsequent ones are dropped to keep error UIs tidy).
|
|
20692
21654
|
*
|
|
21655
|
+
* The map is a plain object, but every key is written as an **own** property
|
|
21656
|
+
* and looked up with `hasOwnProperty`: with `path in errors` and `errors[path] =`
|
|
21657
|
+
* a field named `constructor` or `toString` read as already failed through
|
|
21658
|
+
* `Object.prototype` and lost its message, and an issue a `superRefine` files
|
|
21659
|
+
* under `__proto__` replaced the map's prototype instead of becoming a key.
|
|
21660
|
+
*
|
|
20693
21661
|
* @param schema - zod schema describing the form shape.
|
|
20694
21662
|
* @param values - Raw form values (typed as `unknown`).
|
|
20695
21663
|
* @returns Either `{ success: true, data, errors: {} }` or `{ success: false, errors }`.
|
|
@@ -21796,6 +22764,12 @@ export declare function writeXlsx(headers: readonly string[], rows: readonly (re
|
|
|
21796
22764
|
* `ResolverOptions` is accepted and ignored, because react-hook-form always
|
|
21797
22765
|
* passes the whole object.
|
|
21798
22766
|
*
|
|
22767
|
+
* Errors are written as **own** properties and checked with `hasOwnProperty`.
|
|
22768
|
+
* A plain `errors[path]` read saw `Object.prototype.constructor` for a field
|
|
22769
|
+
* named `constructor`, so `firstError` mode kept the inherited function instead
|
|
22770
|
+
* of the message, and an issue a `superRefine` files under `__proto__` replaced
|
|
22771
|
+
* the map's prototype instead of adding the field.
|
|
22772
|
+
*
|
|
21799
22773
|
* @example
|
|
21800
22774
|
* const form = useForm<LoginForm>({ resolver: zodResolver(loginSchema) });
|
|
21801
22775
|
*/
|