tempest-react-sdk 0.79.0 → 0.81.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 +35 -4
- package/bin/lib/component/generate.test.mjs +13 -1
- package/bin/lib/openapi/generate.hostile.test.mjs +58 -5
- package/bin/lib/openapi/generate.mjs +145 -34
- package/bin/lib/openapi/generate.test.mjs +216 -5
- package/bin/lib/openapi/schema-to-zod.mjs +4 -3
- 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 +172 -103
- package/dist/auth/create-tempest-auth.js.map +1 -1
- 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 +29 -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 +91 -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/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/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/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +104 -97
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/build-url.cjs +1 -1
- package/dist/http/build-url.cjs.map +1 -1
- package/dist/http/build-url.js +3 -1
- package/dist/http/build-url.js.map +1 -1
- package/dist/http/presigned-post.cjs +2 -0
- package/dist/http/presigned-post.cjs.map +1 -0
- package/dist/http/presigned-post.js +73 -0
- package/dist/http/presigned-post.js.map +1 -0
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +97 -97
- 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 +12 -12
- 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/offline/create-offline-sync.cjs +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js +78 -56
- package/dist/offline/create-offline-sync.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 +44 -30
- package/dist/sse/create-event-stream.js.map +1 -1
- package/dist/sse/ticket-event-stream.cjs +2 -0
- package/dist/sse/ticket-event-stream.cjs.map +1 -0
- package/dist/sse/ticket-event-stream.js +41 -0
- package/dist/sse/ticket-event-stream.js.map +1 -0
- 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 +7 -4
- 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 +124 -106
- package/dist/sw/background-sync.js.map +1 -1
- package/dist/sw.d.ts +49 -15
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +809 -22
- package/dist/tempest-react-sdk.js +373 -363
- 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/package.json +1 -1
- package/template-pwa/src/sw.ts +10 -6
|
@@ -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';
|
|
@@ -768,6 +769,20 @@ export declare interface ApiClient {
|
|
|
768
769
|
*/
|
|
769
770
|
arrayBuffer(path: string, options?: RequestOptions): Promise<ArrayBuffer>;
|
|
770
771
|
upload<T>(path: string, formData: FormData, method?: "POST" | "PUT" | "PATCH", options?: Omit<RequestOptions, "body" | "method">): Promise<T>;
|
|
772
|
+
/**
|
|
773
|
+
* The absolute URL a request to `path` would hit, without sending one.
|
|
774
|
+
*
|
|
775
|
+
* For the consumers that cannot go through `fetch` but must land on the
|
|
776
|
+
* same host: an `EventSource`, an `<img src>`, a download link. Rebuilding
|
|
777
|
+
* the URL by hand duplicates `baseURL` and `prefix`, and a forgotten prefix
|
|
778
|
+
* is a silent 404. No credential is attached: the URL is a string, and a
|
|
779
|
+
* token placed in it would end up in every proxy log.
|
|
780
|
+
*
|
|
781
|
+
* @param path - Path joined onto the client's base URL and prefix.
|
|
782
|
+
* @param params - Query params to append; `undefined` and `null` are skipped.
|
|
783
|
+
* @returns The absolute URL.
|
|
784
|
+
*/
|
|
785
|
+
url(path: string, params?: RequestOptions["params"]): string;
|
|
771
786
|
}
|
|
772
787
|
|
|
773
788
|
export declare interface ApiClientConfig {
|
|
@@ -856,7 +871,10 @@ export declare interface ApiClientConfig {
|
|
|
856
871
|
* Never logs a body, a header, or the query string — a bearer token in
|
|
857
872
|
* `Authorization`, a password in a login payload and an `access_token` query
|
|
858
873
|
* param would all end up in whatever the sink writes to. What is logged is
|
|
859
|
-
* 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.
|
|
860
878
|
*/
|
|
861
879
|
logger?: ApiClientLogger;
|
|
862
880
|
/**
|
|
@@ -1769,6 +1787,152 @@ export declare interface AudioRecording {
|
|
|
1769
1787
|
durationMs: number;
|
|
1770
1788
|
}
|
|
1771
1789
|
|
|
1790
|
+
/**
|
|
1791
|
+
* An e-mail field: trimmed and lower-cased *before* it is validated.
|
|
1792
|
+
*
|
|
1793
|
+
* The order is the point. Validating first rejects `" ana@x.com"` pasted with a
|
|
1794
|
+
* trailing space from a password manager, and a backend that compares e-mails
|
|
1795
|
+
* case-sensitively creates a second account for `Ana@x.com`. An empty value gets
|
|
1796
|
+
* its own sentence instead of "e-mail inválido", which reads like an accusation
|
|
1797
|
+
* on a field the user simply has not reached yet.
|
|
1798
|
+
*
|
|
1799
|
+
* @returns A schema producing the normalized address.
|
|
1800
|
+
*/
|
|
1801
|
+
export declare function authEmail(): z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* One entry of an auth form's `fields` list.
|
|
1805
|
+
*
|
|
1806
|
+
* The form is generated from this list, so the app declares *which* fields and
|
|
1807
|
+
* *how they read* — never the markup, the wiring to react-hook-form or the error
|
|
1808
|
+
* slot.
|
|
1809
|
+
*
|
|
1810
|
+
* @typeParam TName - The schema's keys, so a typo in `name` fails to compile.
|
|
1811
|
+
*/
|
|
1812
|
+
export declare interface AuthField<TName extends string = string> {
|
|
1813
|
+
/** Key in the schema and in the submitted values. */
|
|
1814
|
+
name: TName;
|
|
1815
|
+
/** Visible label. Rich content works for `checkbox` (a terms link); keep it text for `pin`. */
|
|
1816
|
+
label: ReactNode;
|
|
1817
|
+
/** Control used to render it. Default `"text"`. */
|
|
1818
|
+
type?: AuthFieldType;
|
|
1819
|
+
/** Placeholder shown while the field is empty. */
|
|
1820
|
+
placeholder?: string;
|
|
1821
|
+
/**
|
|
1822
|
+
* `autocomplete` token. Defaults per type: `email` → `"email"`, `password` →
|
|
1823
|
+
* `"current-password"`, `phone` → `"tel"`. Sign-up and reset presets pass
|
|
1824
|
+
* `"new-password"` so password managers offer to generate one.
|
|
1825
|
+
*/
|
|
1826
|
+
autoComplete?: string;
|
|
1827
|
+
/** Help text under the field, replaced by the error when there is one. */
|
|
1828
|
+
helperText?: ReactNode;
|
|
1829
|
+
/** Marks the control as required (visual hint + native attribute). */
|
|
1830
|
+
required?: boolean;
|
|
1831
|
+
/** `password` only: show the strength meter under the field. */
|
|
1832
|
+
showStrength?: boolean;
|
|
1833
|
+
/** `pin` only: number of cells. Default `6`. */
|
|
1834
|
+
length?: number;
|
|
1835
|
+
/** Render the control yourself — for a field none of the types covers. */
|
|
1836
|
+
render?: (props: AuthFieldRenderProps) => ReactNode;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
/** The field names a schema accepts. */
|
|
1840
|
+
export declare type AuthFieldName<TSchema extends z.ZodTypeAny> = Extract<keyof z.infer<TSchema>, string>;
|
|
1841
|
+
|
|
1842
|
+
/** What a field's `render` receives: the react-hook-form binding plus the field's own config. */
|
|
1843
|
+
export declare interface AuthFieldRenderProps {
|
|
1844
|
+
/** `name`, `value`, `onChange`, `onBlur` and `ref` — spread or wire them into the control. */
|
|
1845
|
+
field: ControllerRenderProps<FieldValues, string>;
|
|
1846
|
+
/** The field's validation state, including the server error mapped onto it. */
|
|
1847
|
+
fieldState: ControllerFieldState;
|
|
1848
|
+
/** The current error message, already resolved from `fieldState`. */
|
|
1849
|
+
error?: string;
|
|
1850
|
+
/** The config entry this field was declared with. */
|
|
1851
|
+
config: AuthField;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
/**
|
|
1855
|
+
* Which SDK control renders a field.
|
|
1856
|
+
*
|
|
1857
|
+
* `text` and `email` → `Input`, `password` → `PasswordInput`, `phone` / `cpf` /
|
|
1858
|
+
* `cnpj` → the masked inputs, `checkbox` → `Checkbox`, `pin` → `PinInput`. The
|
|
1859
|
+
* list is closed on purpose: these are the controls an auth screen uses, and
|
|
1860
|
+
* anything else goes through `render`.
|
|
1861
|
+
*/
|
|
1862
|
+
export declare type AuthFieldType = "text" | "email" | "password" | "phone" | "cpf" | "cnpj" | "checkbox" | "pin";
|
|
1863
|
+
|
|
1864
|
+
/**
|
|
1865
|
+
* A complete auth form generated from a list of field configs and a zod schema.
|
|
1866
|
+
*
|
|
1867
|
+
* Every hand-built login and sign-up screen repeated the same wiring: a
|
|
1868
|
+
* `useZodForm`, one labelled input per field with its error slot, a password eye,
|
|
1869
|
+
* a submit button disabled while the request runs, and a `catch` that copied the
|
|
1870
|
+
* 422's field messages back onto the inputs. The app now declares *which* fields
|
|
1871
|
+
* and *what happens on submit*; the rest is here, built on the SDK's own controls
|
|
1872
|
+
* and its forms layer (`useZodForm` + `FormProvider` + `FormField`).
|
|
1873
|
+
*
|
|
1874
|
+
* Errors thrown by `onSubmit` are shown, never rethrown — a rethrow from a submit
|
|
1875
|
+
* handler is an unhandled rejection with nowhere to go. A `TempestApiError` whose
|
|
1876
|
+
* `fields` name fields of this form marks them; anything else, and any field
|
|
1877
|
+
* message that matched no declared field, goes to an `Alert` above the fields,
|
|
1878
|
+
* worded by `describeApiError`. Pass `onError` to log.
|
|
1879
|
+
*
|
|
1880
|
+
* @example
|
|
1881
|
+
* const schema = z.object({ email: z.email("E-mail inválido") });
|
|
1882
|
+
* <AuthForm
|
|
1883
|
+
* schema={schema}
|
|
1884
|
+
* fields={[{ name: "email", type: "email", label: "E-mail" }]}
|
|
1885
|
+
* submitLabel="Continuar"
|
|
1886
|
+
* onSubmit={async (values) => { await api.post("/auth/magic-link", { body: values }); }}
|
|
1887
|
+
* />
|
|
1888
|
+
*/
|
|
1889
|
+
export declare function AuthForm<TSchema extends z.ZodTypeAny>({ schema, fields, onSubmit, submitLabel, defaultValues, beforeSubmit, afterSubmit, social, labels, errorOptions, onError, className, }: AuthFormProps<TSchema>): ReactNode;
|
|
1890
|
+
|
|
1891
|
+
/** Fixed sentences of {@link AuthFormProps}, PT-BR by default. */
|
|
1892
|
+
export declare interface AuthFormLabels {
|
|
1893
|
+
/** Text of the divider drawn above the `social` slot. Default `"ou"`. */
|
|
1894
|
+
divider: string;
|
|
1895
|
+
/**
|
|
1896
|
+
* Fallback sentence of the error alert, when the thrown error carries nothing
|
|
1897
|
+
* better. Default `"Não foi possível concluir agora. Tente de novo."`.
|
|
1898
|
+
*/
|
|
1899
|
+
error: string;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
export declare interface AuthFormProps<TSchema extends z.ZodTypeAny> {
|
|
1903
|
+
/** Zod schema validating the values; its messages are what each field shows. */
|
|
1904
|
+
schema: TSchema;
|
|
1905
|
+
/** The fields, in display order. */
|
|
1906
|
+
fields: readonly AuthField<AuthFieldName<TSchema>>[];
|
|
1907
|
+
/**
|
|
1908
|
+
* Called with the validated values. Throw to fail: a `TempestApiError` whose
|
|
1909
|
+
* `fields` name fields of this form marks those fields; any other error shows
|
|
1910
|
+
* an alert above the form.
|
|
1911
|
+
*/
|
|
1912
|
+
onSubmit: (values: z.infer<TSchema>) => Promise<void> | void;
|
|
1913
|
+
/** Submit button content. Default `"Enviar"`. */
|
|
1914
|
+
submitLabel?: ReactNode;
|
|
1915
|
+
/** Initial values. Fields left out start as `""` (`false` for checkboxes). */
|
|
1916
|
+
defaultValues?: Partial<z.input<TSchema>>;
|
|
1917
|
+
/** Content between the fields and the submit button — the "forgot password" link. */
|
|
1918
|
+
beforeSubmit?: ReactNode;
|
|
1919
|
+
/** Content after the submit button — the "no account? sign up" line. */
|
|
1920
|
+
afterSubmit?: ReactNode;
|
|
1921
|
+
/** Social sign-in buttons. Rendered under a divider reading `labels.divider`. */
|
|
1922
|
+
social?: ReactNode;
|
|
1923
|
+
/** Overrides for the fixed sentences. */
|
|
1924
|
+
labels?: Partial<AuthFormLabels>;
|
|
1925
|
+
/** Passed to `describeApiError` to word the alert — map error `codes`, `statuses`. */
|
|
1926
|
+
errorOptions?: DescribeApiErrorOptions;
|
|
1927
|
+
/** Called with every error `onSubmit` threw, after it is shown — for logging. */
|
|
1928
|
+
onError?: (error: unknown) => void;
|
|
1929
|
+
/** Class name for the `<form>`. */
|
|
1930
|
+
className?: string;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
/** The value object a schema produces, as react-hook-form sees it. */
|
|
1934
|
+
export declare type AuthFormValues<TSchema extends z.ZodTypeAny> = z.infer<TSchema> & FieldValues;
|
|
1935
|
+
|
|
1772
1936
|
/**
|
|
1773
1937
|
* Router-agnostic auth gate. The caller decides what to render in either
|
|
1774
1938
|
* branch — typically `<Outlet />` for protected layouts and `<Navigate />` for
|
|
@@ -1793,6 +1957,122 @@ export declare interface AuthGuardProps {
|
|
|
1793
1957
|
fallback: ReactNode;
|
|
1794
1958
|
}
|
|
1795
1959
|
|
|
1960
|
+
/**
|
|
1961
|
+
* The layout shell of a sign-in, sign-up or password-recovery screen.
|
|
1962
|
+
*
|
|
1963
|
+
* Every app was hand-building the same page around its form: a colored top with
|
|
1964
|
+
* the logo and a back button over a white sheet with rounded top corners on
|
|
1965
|
+
* mobile, a 50/50 brand panel and form on desktop, a "Bem-vindo!" heading. This
|
|
1966
|
+
* component is that page, so the app passes only the brand and the form.
|
|
1967
|
+
*
|
|
1968
|
+
* The switch between the two layouts is a JavaScript media query, not a CSS
|
|
1969
|
+
* `@media` rule, because the breakpoint is a prop: a CSS media query cannot read a
|
|
1970
|
+
* custom property. `useMediaQuery` evaluates synchronously on the first render, so
|
|
1971
|
+
* a client-rendered page does not flash the wrong layout.
|
|
1972
|
+
*
|
|
1973
|
+
* @example
|
|
1974
|
+
* <AuthPage brand={<img src="/logo.svg" alt="Acme" />} back="/" title="Bem-vindo!">
|
|
1975
|
+
* <LoginForm onSubmit={signIn} links={{ forgotPassword: "/recuperar", signUp: "/cadastro" }} />
|
|
1976
|
+
* </AuthPage>
|
|
1977
|
+
*/
|
|
1978
|
+
export declare function AuthPage({ brand, title, subtitle, aside, variant, breakpoint, back, footer, headingLevel, as, children, className, style, ...props }: AuthPageProps): ReactNode;
|
|
1979
|
+
|
|
1980
|
+
/** The brand panel of a `split` page — the colored half on desktop, the colored top on mobile. */
|
|
1981
|
+
export declare interface AuthPageAside {
|
|
1982
|
+
/**
|
|
1983
|
+
* Any CSS `background` value: a color, a token, a gradient, an image.
|
|
1984
|
+
* Defaults to `var(--tempest-primary)`, so a themed app gets its brand color
|
|
1985
|
+
* without passing anything.
|
|
1986
|
+
*/
|
|
1987
|
+
background?: string;
|
|
1988
|
+
/**
|
|
1989
|
+
* Text color over that background. Defaults to `var(--tempest-text-on-primary)`,
|
|
1990
|
+
* which is only right while the background is the primary color — set it
|
|
1991
|
+
* together with a custom `background` so the back button and the app name
|
|
1992
|
+
* keep their contrast.
|
|
1993
|
+
*/
|
|
1994
|
+
color?: string;
|
|
1995
|
+
/** Extra content under the brand on the panel: a tagline, an illustration. */
|
|
1996
|
+
content?: ReactNode;
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
/** The back action, as an object when the label or the behavior is not the default. */
|
|
2000
|
+
export declare interface AuthPageBackAction {
|
|
2001
|
+
/** Route to navigate to, rendered as a router `Link`. */
|
|
2002
|
+
to?: string;
|
|
2003
|
+
/** Visible label (and accessible name). Default `"Voltar"`. */
|
|
2004
|
+
label?: string;
|
|
2005
|
+
/** Click handler — used alone (a `<button>`) or together with `to`. */
|
|
2006
|
+
onClick?: () => void;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
/** Heading level of the page title. */
|
|
2010
|
+
export declare type AuthPageHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
2011
|
+
|
|
2012
|
+
export declare interface AuthPageProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
2013
|
+
/** Logo and/or app name, shown on the brand panel (split) or at the top of the card. */
|
|
2014
|
+
brand?: ReactNode;
|
|
2015
|
+
/** Page title, rendered as a heading — e.g. `"Bem-vindo!"`. */
|
|
2016
|
+
title?: ReactNode;
|
|
2017
|
+
/** Line under the title — e.g. `"Entre com sua conta para continuar"`. */
|
|
2018
|
+
subtitle?: ReactNode;
|
|
2019
|
+
/** Brand panel colors and extra content. */
|
|
2020
|
+
aside?: AuthPageAside;
|
|
2021
|
+
/**
|
|
2022
|
+
* `split` (default): colored top + rounded white sheet below `breakpoint`,
|
|
2023
|
+
* 50/50 brand panel and form at or above it. `card`: one centered card at
|
|
2024
|
+
* every width — the internal-panel login.
|
|
2025
|
+
*/
|
|
2026
|
+
variant?: AuthPageVariant;
|
|
2027
|
+
/**
|
|
2028
|
+
* Viewport width, in px, at which `split` turns into two columns. Default
|
|
2029
|
+
* `768`, the width every hand-built auth screen this replaces switched at —
|
|
2030
|
+
* deliberately not the `1024` of `useBreakpoint`, which is about navigation
|
|
2031
|
+
* chrome, not about whether a form fits beside a brand panel.
|
|
2032
|
+
*/
|
|
2033
|
+
breakpoint?: number;
|
|
2034
|
+
/** Back action: a route string, or an object with `to`/`label`/`onClick`. Omit to hide it. */
|
|
2035
|
+
back?: string | AuthPageBackAction;
|
|
2036
|
+
/** Content under the form, inside the sheet or card — legal text, a secondary link. */
|
|
2037
|
+
footer?: ReactNode;
|
|
2038
|
+
/** Heading level of `title`. Default `1`, since the auth screen is usually the whole page. */
|
|
2039
|
+
headingLevel?: AuthPageHeadingLevel;
|
|
2040
|
+
/**
|
|
2041
|
+
* Root element. Default `"main"`, the page's main landmark. Use `"div"` when
|
|
2042
|
+
* the page is rendered inside a layout that already owns a `<main>` — two
|
|
2043
|
+
* nested main landmarks are an accessibility violation.
|
|
2044
|
+
*/
|
|
2045
|
+
as?: "main" | "div";
|
|
2046
|
+
/** The form — usually an `AuthForm` or one of its presets. */
|
|
2047
|
+
children?: ReactNode;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
/** How the page is laid out: brand panel beside the form, or one centered card. */
|
|
2051
|
+
export declare type AuthPageVariant = "split" | "card";
|
|
2052
|
+
|
|
2053
|
+
/**
|
|
2054
|
+
* A password field with the minimum length every Tempest backend enforces.
|
|
2055
|
+
*
|
|
2056
|
+
* @param message - Sentence shown below 8 characters.
|
|
2057
|
+
* @returns The password schema.
|
|
2058
|
+
*/
|
|
2059
|
+
export declare function authPassword(message?: string): z.ZodString;
|
|
2060
|
+
|
|
2061
|
+
/**
|
|
2062
|
+
* Props every preset (`LoginForm`, `SignUpForm`, …) shares.
|
|
2063
|
+
*
|
|
2064
|
+
* `schema` and `fields` become optional — the preset ships both — and the slots
|
|
2065
|
+
* around the submit button are the preset's to fill, from its `links`.
|
|
2066
|
+
*
|
|
2067
|
+
* @typeParam TSchema - The schema in use; the preset's default when none is passed.
|
|
2068
|
+
*/
|
|
2069
|
+
export declare interface AuthPresetProps<TSchema extends z.ZodTypeAny> extends Omit<AuthFormProps<TSchema>, "schema" | "fields" | "labels" | "beforeSubmit" | "afterSubmit"> {
|
|
2070
|
+
/** Replaces the preset's schema. Pair it with `fields` when it adds or renames keys. */
|
|
2071
|
+
schema?: TSchema;
|
|
2072
|
+
/** Replaces the preset's field list. */
|
|
2073
|
+
fields?: readonly AuthField<AuthFieldName<TSchema>>[];
|
|
2074
|
+
}
|
|
2075
|
+
|
|
1796
2076
|
export declare interface AuthState<TUser> {
|
|
1797
2077
|
user: TUser | null;
|
|
1798
2078
|
token: string | null;
|
|
@@ -2417,7 +2697,10 @@ export { BrowserRouter }
|
|
|
2417
2697
|
*
|
|
2418
2698
|
* A path that is itself an absolute URL wins over all of this, which is how a
|
|
2419
2699
|
* client reaches a second host (a signed upload endpoint, a CDN) without a
|
|
2420
|
-
* second client.
|
|
2700
|
+
* second client. Without `params` it is returned exactly as given: a signed
|
|
2701
|
+
* URL covers its query, and a round trip through `URL` re-encodes characters
|
|
2702
|
+
* outside the canonical form (`'` became `%27`, measured), which is a rewrite
|
|
2703
|
+
* of a string the server signed.
|
|
2421
2704
|
*
|
|
2422
2705
|
* @example
|
|
2423
2706
|
* buildApiUrl("https://api.example.com", "/auth/login", { prefix: "/api" });
|
|
@@ -4220,11 +4503,15 @@ export declare function createDataProvider(client: ApiClient, options?: DataProv
|
|
|
4220
4503
|
* `onMessage`. Pass `withCredentials: true` when the backend authenticates via
|
|
4221
4504
|
* cookies. Call `close()` from the returned controller to tear down.
|
|
4222
4505
|
*
|
|
4223
|
-
*
|
|
4506
|
+
* When `url` is a function it is called before every connection, so a
|
|
4507
|
+
* reconnect presents a fresh credential instead of the one that expired. A
|
|
4508
|
+
* resolution still pending when `close()` or `reconnect()` runs is discarded.
|
|
4509
|
+
*
|
|
4510
|
+
* @param url - Full SSE endpoint URL, or a function returning it per connection.
|
|
4224
4511
|
* @param options - Stream configuration and callbacks.
|
|
4225
4512
|
* @returns A controller exposing `close`, `reconnect` and the current `status`.
|
|
4226
4513
|
*/
|
|
4227
|
-
export declare function createEventStream<T = unknown>(url:
|
|
4514
|
+
export declare function createEventStream<T = unknown>(url: EventStreamUrl, options?: CreateEventStreamOptions<T>): EventStreamController;
|
|
4228
4515
|
|
|
4229
4516
|
export declare interface CreateEventStreamOptions<T> {
|
|
4230
4517
|
/** Send cookies with the EventSource handshake. Default: false. */
|
|
@@ -4279,6 +4566,21 @@ export declare interface CreateEventStreamOptions<T> {
|
|
|
4279
4566
|
* `isDevBuild()` to be able to answer, and this callback is the app's own.
|
|
4280
4567
|
*/
|
|
4281
4568
|
onValidationError?: (issues: SchemaIssue[], raw: string) => void;
|
|
4569
|
+
/**
|
|
4570
|
+
* The URL function threw or rejected, so no connection was attempted.
|
|
4571
|
+
*
|
|
4572
|
+
* `onError` cannot carry this: it receives the `EventSource` `Event`, and a
|
|
4573
|
+
* URL that never resolved never had an `EventSource`.
|
|
4574
|
+
*/
|
|
4575
|
+
onUrlError?: (error: unknown) => void;
|
|
4576
|
+
/**
|
|
4577
|
+
* Whether a URL-resolution failure is worth another attempt. Default: always.
|
|
4578
|
+
*
|
|
4579
|
+
* Return `false` for failures no backoff can fix — a `401` or a `403` when
|
|
4580
|
+
* fetching a ticket is a session decision, not a network blip — and the stream
|
|
4581
|
+
* stops at `status: "error"` instead of spending `maxRetries` on it.
|
|
4582
|
+
*/
|
|
4583
|
+
shouldRetryUrl?: (error: unknown) => boolean;
|
|
4282
4584
|
onOpen?: () => void;
|
|
4283
4585
|
onMessage?: (message: EventStreamMessage<T>) => void;
|
|
4284
4586
|
onError?: (error: Event) => void;
|
|
@@ -5216,6 +5518,17 @@ export declare interface CreateStorePersistOptions<T> {
|
|
|
5216
5518
|
* without a working revocation, that boot `refresh()` restores the previous
|
|
5217
5519
|
* account for whoever uses the browser next.
|
|
5218
5520
|
*
|
|
5521
|
+
* With `storage: "local"` the session belongs to the **origin**, not the tab:
|
|
5522
|
+
* every tab reads and writes the same keys and follows what another tab wrote
|
|
5523
|
+
* — on the `storage` event and, before any refresh, `logout()` or ending of
|
|
5524
|
+
* the session, by comparing the stored session with the one it holds. A
|
|
5525
|
+
* rotation elsewhere is adopted; a logout or another account's login
|
|
5526
|
+
* elsewhere ends the session here too, with `onSessionEnd` told it happened
|
|
5527
|
+
* `elsewhere`. Before 0.81.0 a tab left open after logout kept account A and,
|
|
5528
|
+
* on its next `401`, redeemed account B's refresh token from the shared
|
|
5529
|
+
* storage, persisting `{ user: A, token: B }` (#524). `storage: "session"` is
|
|
5530
|
+
* per tab and behaves as before.
|
|
5531
|
+
*
|
|
5219
5532
|
* Refreshes are collapsed per rotation, not just per overlap: a `401` whose
|
|
5220
5533
|
* request left with a token that has since been replaced in the same session
|
|
5221
5534
|
* replays with the new token and refreshes nothing. Three expired requests take
|
|
@@ -5478,6 +5791,35 @@ export declare interface CreateThemeOptions {
|
|
|
5478
5791
|
inverseSelector?: string;
|
|
5479
5792
|
}
|
|
5480
5793
|
|
|
5794
|
+
/**
|
|
5795
|
+
* Open the ticket-authenticated stream of the `tempest-fastapi-sdk` SSE router.
|
|
5796
|
+
*
|
|
5797
|
+
* `POST <prefix>/ticket` through the authenticated client, then
|
|
5798
|
+
* `GET <prefix>/stream?ticket=…` — and again for every reconnect, because the
|
|
5799
|
+
* ticket only opens streams for `expires_in` seconds and a reconnect after that
|
|
5800
|
+
* with the old one is a `401`. A ticket request refused with a status no
|
|
5801
|
+
* backoff fixes (`401`, `403 ACCOUNT_INACTIVE`) stops the stream at
|
|
5802
|
+
* `status: "error"` and reaches `onUrlError`; pass `shouldRetryUrl` to replace
|
|
5803
|
+
* {@link isRetriableTicketError}.
|
|
5804
|
+
*
|
|
5805
|
+
* The access token never enters the URL: it travels as the client's header (or
|
|
5806
|
+
* cookie) on the ticket request, and the ticket in the URL opens that stream
|
|
5807
|
+
* and nothing else.
|
|
5808
|
+
*
|
|
5809
|
+
* @example
|
|
5810
|
+
* const stream = createTicketEventStream<Notification>({
|
|
5811
|
+
* client: api,
|
|
5812
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
5813
|
+
* onUrlError: (error) => toast.error(describeApiError(error)),
|
|
5814
|
+
* });
|
|
5815
|
+
*
|
|
5816
|
+
* @param options - Ticket source plus every {@link createEventStream} option.
|
|
5817
|
+
* @returns The stream controller.
|
|
5818
|
+
*/
|
|
5819
|
+
export declare function createTicketEventStream<T = unknown>(options: CreateTicketEventStreamOptions<T>): EventStreamController;
|
|
5820
|
+
|
|
5821
|
+
export declare type CreateTicketEventStreamOptions<T> = TicketEventStreamSource & CreateEventStreamOptions<T>;
|
|
5822
|
+
|
|
5481
5823
|
/**
|
|
5482
5824
|
* Record a video stream — a camera, a screen share, or a `canvas.captureStream()`.
|
|
5483
5825
|
*
|
|
@@ -6489,6 +6831,9 @@ export declare function deepMerge<T>(target: T, source: Partial<T>): T;
|
|
|
6489
6831
|
*/
|
|
6490
6832
|
export declare const DEFAULT_API_ERROR_STRINGS: ApiErrorStrings;
|
|
6491
6833
|
|
|
6834
|
+
/** PT-BR defaults of {@link AuthFormLabels}. */
|
|
6835
|
+
export declare const DEFAULT_AUTH_FORM_LABELS: AuthFormLabels;
|
|
6836
|
+
|
|
6492
6837
|
/**
|
|
6493
6838
|
* What a scanner looks for when you do not say.
|
|
6494
6839
|
*
|
|
@@ -7326,6 +7671,19 @@ export declare interface EventStreamMessage<T> {
|
|
|
7326
7671
|
|
|
7327
7672
|
export declare type EventStreamStatus = "idle" | "connecting" | "open" | "closed" | "error";
|
|
7328
7673
|
|
|
7674
|
+
/**
|
|
7675
|
+
* Where the stream connects: a fixed URL, or a function resolved again before
|
|
7676
|
+
* every connection, the first one and each reconnect.
|
|
7677
|
+
*
|
|
7678
|
+
* The function form exists for short-lived credentials carried in the URL,
|
|
7679
|
+
* such as the `?ticket=` of the `tempest-fastapi-sdk` SSE router. `EventSource`
|
|
7680
|
+
* cannot send headers, so the credential has to ride in the query, and one that
|
|
7681
|
+
* expires makes a fixed URL a trap: the reconnect after the expiry presents the
|
|
7682
|
+
* same dead credential, gets a `401`, and burns every retry on it while the user
|
|
7683
|
+
* is still signed in.
|
|
7684
|
+
*/
|
|
7685
|
+
export declare type EventStreamUrl = string | (() => string | Promise<string>);
|
|
7686
|
+
|
|
7329
7687
|
/**
|
|
7330
7688
|
* Finish a `tempest-fastapi-sdk` social login from the SPA's callback route.
|
|
7331
7689
|
*
|
|
@@ -7812,6 +8170,51 @@ declare type FloatingActionButtonVariant = "primary" | "surface";
|
|
|
7812
8170
|
*/
|
|
7813
8171
|
export declare function For<T>({ each, children, fallback }: ForProps<T>): ReactNode;
|
|
7814
8172
|
|
|
8173
|
+
/** Default fields of `ForgotPasswordForm`: the e-mail, with a line saying what happens next. */
|
|
8174
|
+
export declare const FORGOT_PASSWORD_FIELDS: readonly AuthField<"email">[];
|
|
8175
|
+
|
|
8176
|
+
/**
|
|
8177
|
+
* "Forgot password" form: the e-mail the reset link goes to.
|
|
8178
|
+
*
|
|
8179
|
+
* The confirmation screen after a successful submit is the app's call — most
|
|
8180
|
+
* backends answer the same whether or not the address exists, so the copy
|
|
8181
|
+
* belongs next to the backend's policy, not here.
|
|
8182
|
+
*
|
|
8183
|
+
* @example
|
|
8184
|
+
* const [sent, setSent] = useState(false);
|
|
8185
|
+
* <ForgotPasswordForm
|
|
8186
|
+
* onSubmit={async (values) => { await api.post("/auth/forgot-password", { body: values }); setSent(true); }}
|
|
8187
|
+
* links={{ signIn: "/login" }}
|
|
8188
|
+
* />
|
|
8189
|
+
*/
|
|
8190
|
+
export declare function ForgotPasswordForm<TSchema extends z.ZodTypeAny = typeof forgotPasswordSchema>({ schema, fields, links, labels, submitLabel, ...props }: ForgotPasswordFormProps<TSchema>): ReactNode;
|
|
8191
|
+
|
|
8192
|
+
/** Sentences of {@link ForgotPasswordForm}, PT-BR by default. */
|
|
8193
|
+
export declare interface ForgotPasswordFormLabels extends AuthFormLabels {
|
|
8194
|
+
/** Default `"Lembrou a senha?"`. */
|
|
8195
|
+
signInPrompt: string;
|
|
8196
|
+
/** Default `"Entrar"`. */
|
|
8197
|
+
signIn: string;
|
|
8198
|
+
}
|
|
8199
|
+
|
|
8200
|
+
/** Routes the forgot-password form links to. */
|
|
8201
|
+
export declare interface ForgotPasswordFormLinks {
|
|
8202
|
+
/** "Entrar" link, under the form. */
|
|
8203
|
+
signIn?: string;
|
|
8204
|
+
}
|
|
8205
|
+
|
|
8206
|
+
export declare interface ForgotPasswordFormProps<TSchema extends z.ZodTypeAny = typeof forgotPasswordSchema> extends AuthPresetProps<TSchema> {
|
|
8207
|
+
/** Where the links go. */
|
|
8208
|
+
links?: ForgotPasswordFormLinks;
|
|
8209
|
+
/** Overrides for the fixed sentences. */
|
|
8210
|
+
labels?: Partial<ForgotPasswordFormLabels>;
|
|
8211
|
+
}
|
|
8212
|
+
|
|
8213
|
+
/** Default schema of `ForgotPasswordForm`: the e-mail the reset link goes to. */
|
|
8214
|
+
export declare const forgotPasswordSchema: z.ZodObject<{
|
|
8215
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
8216
|
+
}, z.core.$strip>;
|
|
8217
|
+
|
|
7815
8218
|
/**
|
|
7816
8219
|
* Form wrapper with a built-in layout variant. Replaces ad-hoc `<form>` +
|
|
7817
8220
|
* `<Stack>` / `<Grid>` boilerplate; pair with [[FormRow]], [[FormSection]],
|
|
@@ -8868,6 +9271,43 @@ export declare interface InstallBackgroundSyncOptions {
|
|
|
8868
9271
|
* persisting and replaying every header, credentials included.
|
|
8869
9272
|
*/
|
|
8870
9273
|
credentialHeaders?: readonly string[];
|
|
9274
|
+
/**
|
|
9275
|
+
* Origins besides the worker's own that a replayed request may carry a
|
|
9276
|
+
* credential header to — typically the API host when it is not the app's
|
|
9277
|
+
* origin (`["https://api.acme.com"]`). Default `[]`: only the worker's origin.
|
|
9278
|
+
*
|
|
9279
|
+
* A credential re-applied at replay comes from the page, so it is the app's
|
|
9280
|
+
* credential, whatever the request originally carried under the same header
|
|
9281
|
+
* name. Before 0.81.0 the worker checked only the name, and a mutation to a
|
|
9282
|
+
* third party that failed offline carrying that party's `Authorization` was
|
|
9283
|
+
* replayed to it with the app's bearer (#523). Now, with the rule
|
|
9284
|
+
* `isTrustedCredentialTarget` enforces on the live `ApiClient`:
|
|
9285
|
+
* - an entry that carried a credential header to an origin outside this
|
|
9286
|
+
* scope is dropped before `beforeReplay` runs — re-sending it without the
|
|
9287
|
+
* credential would be a request the app never made, and with the app's
|
|
9288
|
+
* credential, a leak;
|
|
9289
|
+
* - a request returned by `beforeReplay` (custom or default) that carries a
|
|
9290
|
+
* header from `credentialHeaders` to an origin outside this scope is
|
|
9291
|
+
* dropped instead of sent.
|
|
9292
|
+
*
|
|
9293
|
+
* Both drops warn once per origin per replay in development builds. Entries
|
|
9294
|
+
* with no credential header are not affected: the browser attaches that
|
|
9295
|
+
* origin's own cookies, as it did on the original attempt.
|
|
9296
|
+
*/
|
|
9297
|
+
trustedOrigins?: readonly string[];
|
|
9298
|
+
/**
|
|
9299
|
+
* How an `"unknown"` owner is handled on an entry with no stripped
|
|
9300
|
+
* credentials (see {@link BackgroundSyncOwnerPolicy}). Default `"strict"`.
|
|
9301
|
+
*
|
|
9302
|
+
* `"lenient"` restores the replay-as-is of 0.77.0 and earlier for an app without sign-in,
|
|
9303
|
+
* where no page ever reports a principal. Do not use it with a cookie
|
|
9304
|
+
* session: the browser attaches on replay the cookie of whoever is signed in
|
|
9305
|
+
* at that moment, so a mutation queued by A whose owner was never stamped
|
|
9306
|
+
* (issuing tab closed, empty `clientId`, stamp lost, legacy entry) goes out
|
|
9307
|
+
* with B's session. Entries with stripped credentials ask the pages either
|
|
9308
|
+
* way. Ignored when a custom `beforeReplay` is given.
|
|
9309
|
+
*/
|
|
9310
|
+
ownerPolicy?: BackgroundSyncOwnerPolicy;
|
|
8871
9311
|
/**
|
|
8872
9312
|
* Prepare each queued request right before it is replayed: return the
|
|
8873
9313
|
* request to send (typically with the current credentials applied) or
|
|
@@ -8895,20 +9335,11 @@ export declare interface InstallBackgroundSyncOptions {
|
|
|
8895
9335
|
* `maxRetentionMinutes` (and warns once per replay in development builds) —
|
|
8896
9336
|
* so a page that never calls {@link provideBackgroundSyncCredentials} leaves
|
|
8897
9337
|
* every entry it queued `"unknown"`, and none of them is replayed.
|
|
8898
|
-
*/
|
|
8899
|
-
/**
|
|
8900
|
-
* How an `"unknown"` owner is handled on an entry with no stripped
|
|
8901
|
-
* credentials (see {@link BackgroundSyncOwnerPolicy}). Default `"strict"`.
|
|
8902
9338
|
*
|
|
8903
|
-
*
|
|
8904
|
-
*
|
|
8905
|
-
*
|
|
8906
|
-
* at that moment, so a mutation queued by A whose owner was never stamped
|
|
8907
|
-
* (issuing tab closed, empty `clientId`, stamp lost, legacy entry) goes out
|
|
8908
|
-
* with B's session. Entries with stripped credentials ask the pages either
|
|
8909
|
-
* way. Ignored when a custom `beforeReplay` is given.
|
|
9339
|
+
* Whatever the hook returns is still held to `trustedOrigins`: a credential
|
|
9340
|
+
* header bound for an origin outside the worker's own and `trustedOrigins` is
|
|
9341
|
+
* never sent.
|
|
8910
9342
|
*/
|
|
8911
|
-
ownerPolicy?: BackgroundSyncOwnerPolicy;
|
|
8912
9343
|
beforeReplay?: (request: Request, context: BackgroundSyncReplayContext) => Request | null | Promise<Request | null>;
|
|
8913
9344
|
}
|
|
8914
9345
|
|
|
@@ -9478,6 +9909,21 @@ export declare function isRejectionCloseCode(code: number): boolean;
|
|
|
9478
9909
|
*/
|
|
9479
9910
|
export declare function isRetriableStatus(status: number): boolean;
|
|
9480
9911
|
|
|
9912
|
+
/**
|
|
9913
|
+
* Whether a failure to obtain a ticket is worth another attempt.
|
|
9914
|
+
*
|
|
9915
|
+
* Only a failure the backoff can outlast is: no response at all, a timeout, a
|
|
9916
|
+
* rate limit, a `5xx`. A `401` reached the caller after the client already
|
|
9917
|
+
* tried its refresh, and a `403` (`ACCOUNT_INACTIVE`) is the backend saying no;
|
|
9918
|
+
* both are session decisions, and retrying them only delays the error state the
|
|
9919
|
+
* app has to show. Anything that is not an API error is a contract mismatch,
|
|
9920
|
+
* which a retry cannot fix either.
|
|
9921
|
+
*
|
|
9922
|
+
* @param error - What the ticket request threw.
|
|
9923
|
+
* @returns Whether to schedule a reconnect.
|
|
9924
|
+
*/
|
|
9925
|
+
export declare function isRetriableTicketError(error: unknown): boolean;
|
|
9926
|
+
|
|
9481
9927
|
export { isRouteErrorResponse }
|
|
9482
9928
|
|
|
9483
9929
|
/** Whether `getDisplayMedia` is reachable at all. */
|
|
@@ -10227,6 +10673,64 @@ export declare interface LoggerSink {
|
|
|
10227
10673
|
(entry: LogEntry): void;
|
|
10228
10674
|
}
|
|
10229
10675
|
|
|
10676
|
+
/**
|
|
10677
|
+
* Default fields of `LoginForm`: e-mail and password.
|
|
10678
|
+
*
|
|
10679
|
+
* Exported, like the other presets' lists, so an app extends the defaults
|
|
10680
|
+
* (`[...LOGIN_FIELDS, { name: "remember", type: "checkbox", … }]`) instead of
|
|
10681
|
+
* retyping them.
|
|
10682
|
+
*/
|
|
10683
|
+
export declare const LOGIN_FIELDS: readonly AuthField<"email" | "password">[];
|
|
10684
|
+
|
|
10685
|
+
/**
|
|
10686
|
+
* Sign-in form: e-mail and password, "forgot password" link, sign-up line and a
|
|
10687
|
+
* slot for social buttons.
|
|
10688
|
+
*
|
|
10689
|
+
* `AuthForm` with the defaults every app wrote by hand: the e-mail trimmed and
|
|
10690
|
+
* lower-cased before validation, `current-password` autocomplete so the saved
|
|
10691
|
+
* password is offered, and the two links in the place users look for them. What
|
|
10692
|
+
* happens on success — storing the session, redirecting — stays in `onSubmit`.
|
|
10693
|
+
*
|
|
10694
|
+
* @example
|
|
10695
|
+
* <LoginForm
|
|
10696
|
+
* onSubmit={async (values) => { await auth.login(values); navigate("/"); }}
|
|
10697
|
+
* links={{ forgotPassword: "/recuperar-senha", signUp: "/cadastro" }}
|
|
10698
|
+
* social={<GoogleSignIn component={GoogleLogin} onSuccess={signInWithGoogle} />}
|
|
10699
|
+
* />
|
|
10700
|
+
*/
|
|
10701
|
+
export declare function LoginForm<TSchema extends z.ZodTypeAny = typeof loginSchema>({ schema, fields, links, labels, submitLabel, ...props }: LoginFormProps<TSchema>): ReactNode;
|
|
10702
|
+
|
|
10703
|
+
/** Sentences of {@link LoginForm}, PT-BR by default. */
|
|
10704
|
+
export declare interface LoginFormLabels extends AuthFormLabels {
|
|
10705
|
+
/** Default `"Esqueceu a senha?"`. */
|
|
10706
|
+
forgotPassword: string;
|
|
10707
|
+
/** Default `"Não tem uma conta?"`. */
|
|
10708
|
+
signUpPrompt: string;
|
|
10709
|
+
/** Default `"Cadastre-se"`. */
|
|
10710
|
+
signUp: string;
|
|
10711
|
+
}
|
|
10712
|
+
|
|
10713
|
+
/** Routes the login form links to. Each link is rendered only when its route is set. */
|
|
10714
|
+
export declare interface LoginFormLinks {
|
|
10715
|
+
/** "Esqueceu a senha?" link, above the submit button. */
|
|
10716
|
+
forgotPassword?: string;
|
|
10717
|
+
/** "Cadastre-se" link, under the form. */
|
|
10718
|
+
signUp?: string;
|
|
10719
|
+
}
|
|
10720
|
+
|
|
10721
|
+
export declare interface LoginFormProps<TSchema extends z.ZodTypeAny = typeof loginSchema> extends AuthPresetProps<TSchema> {
|
|
10722
|
+
/** Where the links go. */
|
|
10723
|
+
links?: LoginFormLinks;
|
|
10724
|
+
/** Overrides for the fixed sentences. */
|
|
10725
|
+
labels?: Partial<LoginFormLabels>;
|
|
10726
|
+
}
|
|
10727
|
+
|
|
10728
|
+
/** Default schema of `LoginForm`: normalized e-mail + password of at least 8 characters. */
|
|
10729
|
+
export declare const loginSchema: z.ZodObject<{
|
|
10730
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
10731
|
+
password: z.ZodString;
|
|
10732
|
+
}, z.core.$strip>;
|
|
10733
|
+
|
|
10230
10734
|
export declare type LogLevel = "debug" | "info" | "warn" | "error";
|
|
10231
10735
|
|
|
10232
10736
|
/**
|
|
@@ -11610,9 +12114,22 @@ export declare interface OfflineSync<TPayload> {
|
|
|
11610
12114
|
pendingCount: () => Promise<number>;
|
|
11611
12115
|
/** The queued mutations in FIFO order. */
|
|
11612
12116
|
listPending: () => Promise<OutboxEntry<TPayload>[]>;
|
|
11613
|
-
/**
|
|
12117
|
+
/**
|
|
12118
|
+
* Drop every queued mutation (e.g. on logout).
|
|
12119
|
+
*
|
|
12120
|
+
* Also ends the current session for any `flush` already in flight: that run
|
|
12121
|
+
* delivers no further entry, pulls and applies nothing more and writes no
|
|
12122
|
+
* watermark, and resolves with `interrupted: true`. A `flush` called after this
|
|
12123
|
+
* starts a fresh run instead of joining the abandoned one.
|
|
12124
|
+
*/
|
|
11614
12125
|
clearOutbox: () => Promise<void>;
|
|
11615
|
-
/**
|
|
12126
|
+
/**
|
|
12127
|
+
* Reset the pull watermark (e.g. on logout / account switch).
|
|
12128
|
+
*
|
|
12129
|
+
* Ends the current session for an in-flight `flush` exactly like
|
|
12130
|
+
* {@link OfflineSync.clearOutbox}, so the run cannot write the ended
|
|
12131
|
+
* session's watermark back after the reset.
|
|
12132
|
+
*/
|
|
11616
12133
|
resetWatermark: () => void;
|
|
11617
12134
|
/** Read the current reactive {@link SyncState} snapshot synchronously. */
|
|
11618
12135
|
getState: () => SyncState;
|
|
@@ -12926,6 +13443,22 @@ export declare type PreloadableLazy<T extends AnyComponent> = ReturnType<typeof
|
|
|
12926
13443
|
}>;
|
|
12927
13444
|
};
|
|
12928
13445
|
|
|
13446
|
+
/**
|
|
13447
|
+
* A pre-signed `POST` form, as `tempest-fastapi-sdk` >= 0.331.0 hands it out
|
|
13448
|
+
* (`presigned_post_policy` / `SubjectObjectStorage.presign_post`).
|
|
13449
|
+
*
|
|
13450
|
+
* Snake case on purpose: this is the wire shape, so it parses straight from the
|
|
13451
|
+
* response of the app's own route.
|
|
13452
|
+
*/
|
|
13453
|
+
export declare interface PresignedPost {
|
|
13454
|
+
/** Where the form is posted: the bucket on S3/MinIO, or the API itself on the local backend. */
|
|
13455
|
+
url: string;
|
|
13456
|
+
/** Form fields to send before the file, in this order — `key`, `policy`, signature and the rest. */
|
|
13457
|
+
fields: Record<string, string>;
|
|
13458
|
+
/** Largest file the policy accepts, in bytes. */
|
|
13459
|
+
max_bytes: number;
|
|
13460
|
+
}
|
|
13461
|
+
|
|
12929
13462
|
/** A model whose cached size should appear in the report. */
|
|
12930
13463
|
export declare interface ProfiledModel {
|
|
12931
13464
|
/** Label for the report row, e.g. `"detector"`. */
|
|
@@ -12996,9 +13529,15 @@ export declare function projectMercator(coord: Coordinate): MercatorPoint;
|
|
|
12996
13529
|
* keeps an entry pending when one it stripped is missing), or `null` when there
|
|
12997
13530
|
* is no session — the worker then drops the entry instead of replaying it
|
|
12998
13531
|
* anonymously. A throw from `getHeaders` or `getPrincipal` is answered as an
|
|
12999
|
-
* explicit `{ error: true }`.
|
|
13000
|
-
*
|
|
13001
|
-
*
|
|
13532
|
+
* explicit `{ error: true }`.
|
|
13533
|
+
*
|
|
13534
|
+
* The worker applies only the header names the original request carried, and
|
|
13535
|
+
* only to the worker's own origin or the `trustedOrigins` given to
|
|
13536
|
+
* {@link installBackgroundSync}: an entry bound for any other origin is dropped
|
|
13537
|
+
* without asking this page. Matching the name is not enough on its own — a
|
|
13538
|
+
* request to a third party carries *that party's* `Authorization`, and until
|
|
13539
|
+
* 0.81.0 its replay received the app's bearer (#523). `getHeaders` still gets
|
|
13540
|
+
* the URL, for an app whose trusted origins need different credentials.
|
|
13002
13541
|
*
|
|
13003
13542
|
* Pass `getPrincipal` to bind each entry to whoever queued it: the worker asks
|
|
13004
13543
|
* the issuing tab right after queueing, asks every tab again before replaying,
|
|
@@ -13848,6 +14387,68 @@ export declare interface RequestOptions extends Omit<RequestInit, "body"> {
|
|
|
13848
14387
|
*/
|
|
13849
14388
|
export declare function requestPersistentStorage(): Promise<boolean>;
|
|
13850
14389
|
|
|
14390
|
+
/** Default fields of `ResetPasswordForm`: new password (with strength meter) and confirmation. */
|
|
14391
|
+
export declare const RESET_PASSWORD_FIELDS: readonly AuthField<"password" | "confirmPassword">[];
|
|
14392
|
+
|
|
14393
|
+
/**
|
|
14394
|
+
* "Choose a new password" form: password and confirmation, with the mismatch
|
|
14395
|
+
* reported under the confirmation field.
|
|
14396
|
+
*
|
|
14397
|
+
* The reset token stays out of the fields: it comes from the URL, and the app
|
|
14398
|
+
* adds it in `onSubmit` — `{ ...values, token }` — where it also decides what an
|
|
14399
|
+
* expired token looks like.
|
|
14400
|
+
*
|
|
14401
|
+
* @example
|
|
14402
|
+
* const [params] = useSearchParams();
|
|
14403
|
+
* <ResetPasswordForm
|
|
14404
|
+
* hints={["Pelo menos 8 caracteres"]}
|
|
14405
|
+
* onSubmit={async (values) => {
|
|
14406
|
+
* await api.post("/auth/reset-password", { body: { ...values, token: params.get("token") } });
|
|
14407
|
+
* }}
|
|
14408
|
+
* />
|
|
14409
|
+
*/
|
|
14410
|
+
export declare function ResetPasswordForm<TSchema extends z.ZodTypeAny = typeof resetPasswordSchema>({ schema, fields, hints, links, labels, submitLabel, ...props }: ResetPasswordFormProps<TSchema>): ReactNode;
|
|
14411
|
+
|
|
14412
|
+
/** Sentences of {@link ResetPasswordForm}, PT-BR by default. */
|
|
14413
|
+
export declare interface ResetPasswordFormLabels extends AuthFormLabels {
|
|
14414
|
+
/** Default `"Lembrou a senha?"`. */
|
|
14415
|
+
signInPrompt: string;
|
|
14416
|
+
/** Default `"Entrar"`. */
|
|
14417
|
+
signIn: string;
|
|
14418
|
+
/** Accessible name of the hints list. Default `"Requisitos da senha"`. */
|
|
14419
|
+
hints: string;
|
|
14420
|
+
}
|
|
14421
|
+
|
|
14422
|
+
/** Routes the reset-password form links to. */
|
|
14423
|
+
export declare interface ResetPasswordFormLinks {
|
|
14424
|
+
/** "Entrar" link, under the form. */
|
|
14425
|
+
signIn?: string;
|
|
14426
|
+
}
|
|
14427
|
+
|
|
14428
|
+
export declare interface ResetPasswordFormProps<TSchema extends z.ZodTypeAny = typeof resetPasswordSchema> extends AuthPresetProps<TSchema> {
|
|
14429
|
+
/**
|
|
14430
|
+
* Password requirements listed above the submit button ("Pelo menos 8
|
|
14431
|
+
* caracteres", "Uma letra maiúscula"). Kept as text the app writes, because
|
|
14432
|
+
* only the backend knows its rules.
|
|
14433
|
+
*/
|
|
14434
|
+
hints?: ReactNode[];
|
|
14435
|
+
/** Where the links go. */
|
|
14436
|
+
links?: ResetPasswordFormLinks;
|
|
14437
|
+
/** Overrides for the fixed sentences. */
|
|
14438
|
+
labels?: Partial<ResetPasswordFormLabels>;
|
|
14439
|
+
}
|
|
14440
|
+
|
|
14441
|
+
/**
|
|
14442
|
+
* Default schema of `ResetPasswordForm`: new password and its confirmation.
|
|
14443
|
+
*
|
|
14444
|
+
* The mismatch is reported on `confirmPassword` (`path`), so the message lands
|
|
14445
|
+
* under the field the user has to fix rather than in a form-level alert.
|
|
14446
|
+
*/
|
|
14447
|
+
export declare const resetPasswordSchema: z.ZodObject<{
|
|
14448
|
+
password: z.ZodString;
|
|
14449
|
+
confirmPassword: z.ZodString;
|
|
14450
|
+
}, z.core.$strip>;
|
|
14451
|
+
|
|
13851
14452
|
/**
|
|
13852
14453
|
* A two-pane split layout with a draggable divider. The first pane is sized via
|
|
13853
14454
|
* `flex-basis` as a percentage; the second pane fills the rest. Drag the divider
|
|
@@ -15484,6 +16085,9 @@ export declare interface SidebarSeparator {
|
|
|
15484
16085
|
key: string;
|
|
15485
16086
|
}
|
|
15486
16087
|
|
|
16088
|
+
/** Default fields of `SignUpForm`: name, e-mail and a password with strength meter. */
|
|
16089
|
+
export declare const SIGN_UP_FIELDS: readonly AuthField<"name" | "email" | "password">[];
|
|
16090
|
+
|
|
15487
16091
|
/**
|
|
15488
16092
|
* Signature capture on a canvas — the "sign here" field of a delivery receipt,
|
|
15489
16093
|
* a service order, a term of acceptance.
|
|
@@ -15555,6 +16159,59 @@ export declare interface SignaturePadProps {
|
|
|
15555
16159
|
className?: string;
|
|
15556
16160
|
}
|
|
15557
16161
|
|
|
16162
|
+
/**
|
|
16163
|
+
* Sign-up form: name, e-mail and password by default, plus the "Já tem uma conta?"
|
|
16164
|
+
* line.
|
|
16165
|
+
*
|
|
16166
|
+
* Apps differ most here — a phone, a CPF, a terms checkbox — so the usual call
|
|
16167
|
+
* passes `fields` and a `schema` built with `signUpSchema.extend({...})`. The
|
|
16168
|
+
* password defaults to `new-password` autocomplete, which is what makes a
|
|
16169
|
+
* password manager offer to generate one.
|
|
16170
|
+
*
|
|
16171
|
+
* @example
|
|
16172
|
+
* <SignUpForm
|
|
16173
|
+
* schema={signUpSchema.extend({ terms: z.literal(true, "Aceite os termos") })}
|
|
16174
|
+
* fields={[...SIGN_UP_FIELDS, { name: "terms", type: "checkbox", label: "Aceito os termos" }]}
|
|
16175
|
+
* onSubmit={async (values) => { await api.post("/auth/register", { body: values }); }}
|
|
16176
|
+
* links={{ signIn: "/login" }}
|
|
16177
|
+
* />
|
|
16178
|
+
*/
|
|
16179
|
+
export declare function SignUpForm<TSchema extends z.ZodTypeAny = typeof signUpSchema>({ schema, fields, links, labels, submitLabel, ...props }: SignUpFormProps<TSchema>): ReactNode;
|
|
16180
|
+
|
|
16181
|
+
/** Sentences of {@link SignUpForm}, PT-BR by default. */
|
|
16182
|
+
export declare interface SignUpFormLabels extends AuthFormLabels {
|
|
16183
|
+
/** Default `"Já tem uma conta?"`. */
|
|
16184
|
+
signInPrompt: string;
|
|
16185
|
+
/** Default `"Entrar"`. */
|
|
16186
|
+
signIn: string;
|
|
16187
|
+
}
|
|
16188
|
+
|
|
16189
|
+
/** Routes the sign-up form links to. */
|
|
16190
|
+
export declare interface SignUpFormLinks {
|
|
16191
|
+
/** "Entrar" link, under the form. */
|
|
16192
|
+
signIn?: string;
|
|
16193
|
+
}
|
|
16194
|
+
|
|
16195
|
+
export declare interface SignUpFormProps<TSchema extends z.ZodTypeAny = typeof signUpSchema> extends AuthPresetProps<TSchema> {
|
|
16196
|
+
/** Where the links go. */
|
|
16197
|
+
links?: SignUpFormLinks;
|
|
16198
|
+
/** Overrides for the fixed sentences. */
|
|
16199
|
+
labels?: Partial<SignUpFormLabels>;
|
|
16200
|
+
}
|
|
16201
|
+
|
|
16202
|
+
/**
|
|
16203
|
+
* Default schema of `SignUpForm`: name, e-mail and password.
|
|
16204
|
+
*
|
|
16205
|
+
* Exported so an app adds its own fields with `.extend()` instead of rewriting
|
|
16206
|
+
* the three it shares with every other app — see the phone and terms example in
|
|
16207
|
+
* the docs.
|
|
16208
|
+
*/
|
|
16209
|
+
export declare const signUpSchema: z.ZodObject<{
|
|
16210
|
+
name: z.ZodString;
|
|
16211
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
16212
|
+
password: z.ZodString;
|
|
16213
|
+
}, z.core.$strip>;
|
|
16214
|
+
|
|
15558
16215
|
/** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
|
|
15559
16216
|
export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
|
|
15560
16217
|
|
|
@@ -15829,6 +16486,14 @@ export declare interface SpinnerProps {
|
|
|
15829
16486
|
|
|
15830
16487
|
export declare type SpinnerSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
15831
16488
|
|
|
16489
|
+
/** Body of `POST <prefix>/ticket` on the `tempest-fastapi-sdk` SSE router. */
|
|
16490
|
+
export declare interface SseTicketResponse {
|
|
16491
|
+
/** Signed stream ticket, presented as a query param when opening the stream. */
|
|
16492
|
+
ticket: string;
|
|
16493
|
+
/** Seconds the ticket is accepted for opening a stream. */
|
|
16494
|
+
expires_in: number;
|
|
16495
|
+
}
|
|
16496
|
+
|
|
15832
16497
|
/** Flex-based vertical or horizontal stack with a numeric `gap`. */
|
|
15833
16498
|
export declare function Stack({ direction, gap, align, justify, wrap, className, style, children, ...props }: StackProps): JSX.Element;
|
|
15834
16499
|
|
|
@@ -16052,6 +16717,16 @@ export declare interface SyncRunSummary {
|
|
|
16052
16717
|
skipped: boolean;
|
|
16053
16718
|
/** Last delivery error message seen this run, or `null` when none failed. */
|
|
16054
16719
|
lastError: string | null;
|
|
16720
|
+
/**
|
|
16721
|
+
* `true` when {@link OfflineSync.clearOutbox} or {@link OfflineSync.resetWatermark}
|
|
16722
|
+
* ended the session while this run was in flight, so it stopped early.
|
|
16723
|
+
*
|
|
16724
|
+
* The counts cover only what happened before the stop: a delivery already in
|
|
16725
|
+
* progress at logout is still counted, but no later entry was sent, no further
|
|
16726
|
+
* page was pulled or applied, and the watermark was not written. Absent on a
|
|
16727
|
+
* run that went to completion.
|
|
16728
|
+
*/
|
|
16729
|
+
interrupted?: true;
|
|
16055
16730
|
}
|
|
16056
16731
|
|
|
16057
16732
|
/**
|
|
@@ -16345,6 +17020,17 @@ export declare interface TempestAuth<TUser, TCredentials> {
|
|
|
16345
17020
|
refresh: () => Promise<void>;
|
|
16346
17021
|
/** The current access token, or null. */
|
|
16347
17022
|
getToken: () => string | null;
|
|
17023
|
+
/**
|
|
17024
|
+
* Stop following the other tabs: removes the `storage` listener this
|
|
17025
|
+
* preset adds to `window`. Idempotent.
|
|
17026
|
+
*
|
|
17027
|
+
* An app keeps one preset for the page's lifetime and never needs it; it
|
|
17028
|
+
* exists for tests and hot-module reload, which build several presets in
|
|
17029
|
+
* one window. A disposed preset still compares the shared storage with
|
|
17030
|
+
* its session before every refresh, so it never redeems another tab's
|
|
17031
|
+
* refresh token.
|
|
17032
|
+
*/
|
|
17033
|
+
dispose: () => void;
|
|
16348
17034
|
}
|
|
16349
17035
|
|
|
16350
17036
|
/**
|
|
@@ -16441,6 +17127,22 @@ declare interface TempestSessionEnd<TUser> {
|
|
|
16441
17127
|
* call to fail and keep the local half of the teardown independent of it.
|
|
16442
17128
|
*/
|
|
16443
17129
|
api: ApiClient;
|
|
17130
|
+
/**
|
|
17131
|
+
* Whether another tab of the origin ended or replaced the session, and this
|
|
17132
|
+
* tab is only catching up (#524). With `storage: "local"` the session's
|
|
17133
|
+
* keys are shared by every tab, so a `logout()` or a `login()` in one tab
|
|
17134
|
+
* ends the session in all of them: `reason` is `"logout"` when the other
|
|
17135
|
+
* tab left no session behind and `"switch"` when it installed another
|
|
17136
|
+
* account.
|
|
17137
|
+
*
|
|
17138
|
+
* The other tab already ran this hook for the same session. Teardown that
|
|
17139
|
+
* lives in this tab's memory (an in-memory cache, an open socket) still has
|
|
17140
|
+
* to run here; teardown of state the origin shares (IndexedDB, Cache
|
|
17141
|
+
* Storage, a push subscription) was done there, and on `"switch"` redoing
|
|
17142
|
+
* it here would wipe what the new account already wrote — skip it when
|
|
17143
|
+
* this is `true`.
|
|
17144
|
+
*/
|
|
17145
|
+
elsewhere: boolean;
|
|
16444
17146
|
}
|
|
16445
17147
|
|
|
16446
17148
|
/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */
|
|
@@ -16581,6 +17283,20 @@ export declare function throttle<A extends unknown[]>(fn: (...args: A) => void,
|
|
|
16581
17283
|
cancel: () => void;
|
|
16582
17284
|
};
|
|
16583
17285
|
|
|
17286
|
+
/** Where the ticket comes from and how the stream URL is built. */
|
|
17287
|
+
export declare interface TicketEventStreamSource {
|
|
17288
|
+
/**
|
|
17289
|
+
* Authenticated client the ticket is requested through, so it carries the
|
|
17290
|
+
* `Authorization` header or the session cookie, the CSRF header, and the
|
|
17291
|
+
* 401 refresh-and-replay that a hand-rolled `fetch` would lose.
|
|
17292
|
+
*/
|
|
17293
|
+
client: Pick<ApiClient, "post" | "url">;
|
|
17294
|
+
/** Router prefix, relative to the client's base URL. Default: `"/sse"`. */
|
|
17295
|
+
prefix?: string;
|
|
17296
|
+
/** Query param the stream reads the ticket from. Default: `"ticket"`. */
|
|
17297
|
+
ticketParam?: string;
|
|
17298
|
+
}
|
|
17299
|
+
|
|
16584
17300
|
/**
|
|
16585
17301
|
* Vertical event timeline — activity feeds, order trackers, audit logs.
|
|
16586
17302
|
* Each entry has a marker (color or custom icon), title, optional
|
|
@@ -17363,6 +18079,48 @@ export declare interface UpdateVariables {
|
|
|
17363
18079
|
*/
|
|
17364
18080
|
export declare function uploadFingerprint(endpoint: string, file: Blob | File): string;
|
|
17365
18081
|
|
|
18082
|
+
/**
|
|
18083
|
+
* Upload a file straight to storage through a pre-signed `POST` form, with the
|
|
18084
|
+
* size ceiling the policy enforces.
|
|
18085
|
+
*
|
|
18086
|
+
* The form is built the way S3 requires: every `post.fields` entry in order,
|
|
18087
|
+
* the file last in the `file` part — S3 ignores whatever follows the file.
|
|
18088
|
+
*
|
|
18089
|
+
* The request carries **no** credential and no custom header: no
|
|
18090
|
+
* `Authorization`, no CSRF token, no `X-Request-ID`, no cookies. `post.url` is
|
|
18091
|
+
* usually the storage host, outside the API's origin, and the signature in
|
|
18092
|
+
* `fields` is the whole authorization. Without custom headers the request is a
|
|
18093
|
+
* CORS "simple request", so it does not depend on the bucket's CORS rules
|
|
18094
|
+
* allowing a preflight.
|
|
18095
|
+
*
|
|
18096
|
+
* A file larger than `post.max_bytes` is refused before anything is sent, with
|
|
18097
|
+
* the same `413 FILE_TOO_LARGE` the server would answer. Server errors are
|
|
18098
|
+
* normalized into one `TempestApiError` whichever backend answered: the S3 XML
|
|
18099
|
+
* (`EntityTooLarge` → `FILE_TOO_LARGE`, `EntityTooSmall` → `FILE_TOO_SMALL`,
|
|
18100
|
+
* `AccessDenied` → `SIGNED_URL_INVALID`, or `SIGNED_URL_EXPIRED` when the policy
|
|
18101
|
+
* expired) or the local backend's JSON envelope, which already uses those codes.
|
|
18102
|
+
*
|
|
18103
|
+
* @example
|
|
18104
|
+
* const post = await api.post<PresignedPost>("/avatars/upload-form");
|
|
18105
|
+
* await uploadPresignedPost(post, file, { onProgress: (p) => setProgress(p.fraction) });
|
|
18106
|
+
*
|
|
18107
|
+
* @param post - The form the API handed out.
|
|
18108
|
+
* @param file - The file or blob to upload.
|
|
18109
|
+
* @param options - Progress callback, abort signal and file name.
|
|
18110
|
+
* @returns Resolves when storage accepted the file (`204` on S3).
|
|
18111
|
+
* @throws TempestApiError On a refused upload, with the normalized `code`.
|
|
18112
|
+
*/
|
|
18113
|
+
export declare function uploadPresignedPost(post: PresignedPost, file: Blob, options?: UploadPresignedPostOptions): Promise<void>;
|
|
18114
|
+
|
|
18115
|
+
export declare interface UploadPresignedPostOptions {
|
|
18116
|
+
/** Called on every `progress` event of the upload. */
|
|
18117
|
+
onProgress?: (event: UploadProgressEvent) => void;
|
|
18118
|
+
/** Abort the upload; rejects with an `AbortError` `DOMException`. */
|
|
18119
|
+
signal?: AbortSignal;
|
|
18120
|
+
/** File name sent with the `file` part. Defaults to `file.name` for a `File`. */
|
|
18121
|
+
fileName?: string;
|
|
18122
|
+
}
|
|
18123
|
+
|
|
17366
18124
|
export declare interface UploadProgressEvent {
|
|
17367
18125
|
/** Bytes already uploaded. */
|
|
17368
18126
|
loaded: number;
|
|
@@ -18144,6 +18902,11 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18144
18902
|
* tied to the component (and the `url`/`enabled` dependencies); the stream
|
|
18145
18903
|
* closes on unmount.
|
|
18146
18904
|
*
|
|
18905
|
+
* A string `url` reopens the stream when it changes. A function `url` does not:
|
|
18906
|
+
* an inline arrow is a new function every render, and keying on its identity
|
|
18907
|
+
* would reconnect on every render. The latest function is the one called on the
|
|
18908
|
+
* next connection, so call `reconnect()` when what it resolves to must change now.
|
|
18909
|
+
*
|
|
18147
18910
|
* Pass `schema` to have every frame validated before it reaches `onMessage`,
|
|
18148
18911
|
* instead of trusting the type argument: without it `data` is announced as `T`
|
|
18149
18912
|
* on the strength of the generic alone, which is a promise about the server
|
|
@@ -18167,7 +18930,7 @@ export declare function useEventListener<K extends keyof HTMLElementEventMap>(ev
|
|
|
18167
18930
|
* onMessage: ({ data }) => addNotification(data),
|
|
18168
18931
|
* });
|
|
18169
18932
|
*/
|
|
18170
|
-
export declare function useEventStream<T = unknown>(url:
|
|
18933
|
+
export declare function useEventStream<T = unknown>(url: EventStreamUrl, options?: UseEventStreamOptions<T>): UseEventStreamResult<T>;
|
|
18171
18934
|
|
|
18172
18935
|
export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange"> {
|
|
18173
18936
|
/** When false, the stream is not opened. Useful for "wait for auth". Default: true. */
|
|
@@ -20186,6 +20949,30 @@ export declare function useTheme(): ThemeContextValue;
|
|
|
20186
20949
|
*/
|
|
20187
20950
|
export declare function useThrottle<T>(value: T, delay: number): T;
|
|
20188
20951
|
|
|
20952
|
+
/**
|
|
20953
|
+
* React form of {@link createTicketEventStream}: same ticket per connection,
|
|
20954
|
+
* lifecycle tied to the component like {@link useEventStream}.
|
|
20955
|
+
*
|
|
20956
|
+
* Changing `client`, `prefix` or `ticketParam` does not drop an open stream:
|
|
20957
|
+
* the next connection uses the new values, and `reconnect()` applies them now.
|
|
20958
|
+
* Reopening on identity would reconnect on every render for a client built
|
|
20959
|
+
* inline.
|
|
20960
|
+
*
|
|
20961
|
+
* @example
|
|
20962
|
+
* const { status } = useTicketEventStream<Notification>({
|
|
20963
|
+
* client: api,
|
|
20964
|
+
* enabled: isAuthenticated,
|
|
20965
|
+
* schema: notificationSchema,
|
|
20966
|
+
* onMessage: ({ data }) => addNotification(data),
|
|
20967
|
+
* });
|
|
20968
|
+
*
|
|
20969
|
+
* @param options - Ticket source plus every {@link useEventStream} option.
|
|
20970
|
+
* @returns Status, last message and `reconnect`.
|
|
20971
|
+
*/
|
|
20972
|
+
export declare function useTicketEventStream<T = unknown>(options: UseTicketEventStreamOptions<T>): UseEventStreamResult<T>;
|
|
20973
|
+
|
|
20974
|
+
export declare type UseTicketEventStreamOptions<T> = TicketEventStreamSource & UseEventStreamOptions<T>;
|
|
20975
|
+
|
|
20189
20976
|
/**
|
|
20190
20977
|
* Run a callback after `delay` ms. Pass `null` to disable. Resets when
|
|
20191
20978
|
* `delay` changes; the callback ref always points at the latest closure.
|