UNPKG

sveltekit-superforms

Version:

Making SvelteKit forms a pleasure to use!

233 lines (232 loc) 11.4 kB
import type { TaintedFields, SuperFormValidated, SuperValidated } from '../superValidate.js'; import type { ActionResult, BeforeNavigate, Page, SubmitFunction, Transport } from '@sveltejs/kit'; import { type Readable, type Writable, type Updater } from 'svelte/store'; import { type FormPathType, type FormPath, type FormPathLeaves } from '../stringPath.js'; import { enhance as kitEnhance } from '$app/forms'; import type { ValidationErrors } from '../superValidate.js'; import type { IsAny, MaybePromise } from '../utils.js'; import type { ClientValidationAdapter, ValidationAdapter } from '../adapters/adapters.js'; import type { InputConstraints } from '../jsonSchema/constraints.js'; import { type ProxyOptions } from './proxies.js'; export type SuperFormEvents<T extends Record<string, unknown>, M> = Pick<FormOptions<T, M>, 'onError' | 'onResult' | 'onSubmit' | 'onUpdate' | 'onUpdated'>; export type SuperFormEventList<T extends Record<string, unknown>, M> = { [Property in keyof SuperFormEvents<T, M>]-?: NonNullable<SuperFormEvents<T, M>[Property]>[]; }; type FilterType<T, Check> = { [K in keyof NonNullable<T> as NonNullable<NonNullable<T>[K]> extends Check ? never : K]: NonNullable<T>[K]; }; /** * Helper type for making ActionResult data strongly typed in onUpdate. * @example const action : FormResult<ActionData> = result.data; */ export type FormResult<T extends Record<string, unknown> | null | undefined> = FilterType<T, SuperValidated<Record<string, unknown>, any, Record<string, unknown>>>; export type TaintOption = boolean | 'untaint' | 'untaint-all' | 'untaint-form'; type ValidatorsOption<T extends Record<string, unknown>> = ValidationAdapter<Partial<T>, Record<string, unknown>> | false | 'clear'; export type FormOptions<T extends Record<string, unknown> = Record<string, unknown>, M = any, In extends Record<string, unknown> = T> = Partial<{ id: string; /** * If `false`, the form won't react to page state updates, except for page invalidations. * If `'never'`, not even page invalidations will affect the form. * @default true */ applyAction: boolean | 'never'; invalidateAll: boolean | 'force' | 'pessimistic'; resetForm: boolean | (() => boolean); scrollToError: 'auto' | 'smooth' | 'off' | boolean | ScrollIntoViewOptions; autoFocusOnError: boolean | 'detect'; errorSelector: string; selectErrorText: boolean; stickyNavbar: string; taintedMessage: string | boolean | null | ((nav: BeforeNavigate) => MaybePromise<boolean>); /** * Enable single page application (SPA) mode. * **The string and failStatus options are deprecated** and will be removed in the next major release. * @see https://superforms.rocks/concepts/spa */ SPA: true | /** @deprecated */ string | /** @deprecated */ { failStatus?: number; }; onSubmit: (input: Parameters<SubmitFunction>[0] & { /** * If dataType: 'json' is set, send this data instead of $form when posting, * and client-side validation for $form passes. * @param data An object that can be serialized with devalue. */ jsonData: (data: Record<string, unknown>) => void; /** * Override client validation temporarily for this form submission. */ validators: (validators: Exclude<ValidatorsOption<T>, 'clear'>) => void; /** * Use a custom fetch or XMLHttpRequest implementation for this form submission. It must return an ActionResult in the response body. * If the request is using a XMLHttpRequest, the promise must be resolved when the request has been completed, not before. */ customRequest: (validators: (input: Parameters<SubmitFunction>[0]) => Promise<Response | XMLHttpRequest | ActionResult>) => void; }) => MaybePromise<unknown | void>; onResult: (event: { result: ActionResult; /** * @deprecated Use formElement instead */ formEl: HTMLFormElement; formElement: HTMLFormElement; cancel: () => void; }) => MaybePromise<unknown | void>; onUpdate: (event: { form: SuperValidated<T, M, In>; /** * @deprecated Use formElement instead */ formEl: HTMLFormElement; formElement: HTMLFormElement; cancel: () => void; result: Required<Extract<ActionResult, { type: 'success' | 'failure'; }>>; }) => MaybePromise<unknown | void>; onUpdated: (event: { form: Readonly<SuperValidated<T, M, In>>; }) => MaybePromise<unknown | void>; onError: 'apply' | ((event: { result: { type: 'error'; status?: number; error: App.Error | Error | { message: string; }; }; }) => MaybePromise<unknown | void>); onChange: (event: ChangeEvent<T>) => void; dataType: 'form' | 'json'; jsonChunkSize: number; validators: ClientValidationAdapter<Partial<T>, Record<string, unknown>> | ValidatorsOption<T>; validationMethod: 'auto' | 'oninput' | 'onblur' | 'onsubmit' | 'submit-only'; customValidity: boolean; clearOnSubmit: 'errors' | 'message' | 'errors-and-message' | 'none'; delayMs: number; timeoutMs: number; multipleSubmits: 'prevent' | 'allow' | 'abort'; syncFlashMessage?: boolean; /** * @deprecated SvelteKit has moved to $app/state instead of $app/stores, making it hard to support both. Use the flash library directly (setFlash or redirect) instead of integrating it with Superforms. */ flashMessage: { module: { getFlash(page: Readable<Page>): Writable<App.PageData['flash']>; updateFlash(page: Readable<Page>, update?: () => Promise<void>): Promise<boolean>; }; onError?: (event: { result: { type: 'error'; status?: number; error: App.Error | Error | { message: string; }; }; flashMessage: Writable<App.PageData['flash']>; }) => MaybePromise<unknown | void>; cookiePath?: string; cookieName?: string; }; warnings: { duplicateId?: boolean; }; transport: IsAny<Transport> extends true ? never : Transport; /** * Version 1 compatibilty mode if true. * Sets resetForm = false and taintedMessage = true. * Add define: { SUPERFORMS_LEGACY: true } to vite.config.ts to enable globally. */ legacy: boolean; }>; export type SuperFormSnapshot<T extends Record<string, unknown>, M = App.Superforms.Message extends never ? any : App.Superforms.Message, In extends Record<string, unknown> = T> = SuperFormValidated<T, M, In> & { tainted: TaintedFields<T> | undefined; }; export type SuperFormData<T extends Record<string, unknown>> = { subscribe: Readable<T>['subscribe']; set(this: void, value: T, options?: { taint?: TaintOption; }): void; update(this: void, updater: Updater<T>, options?: { taint?: TaintOption; }): void; }; export type SuperFormErrors<T extends Record<string, unknown>> = { subscribe: Writable<ValidationErrors<T>>['subscribe']; set(this: void, value: ValidationErrors<T>, options?: { force?: boolean; }): void; update(this: void, updater: Updater<ValidationErrors<T>>, options?: { force?: boolean; }): void; clear: () => void; }; type ResetOptions<T extends Record<string, unknown>> = { keepMessage?: boolean; data?: Partial<T>; newState?: Partial<T>; id?: string; }; type Capture<T extends Record<string, unknown>, M = App.Superforms.Message extends never ? any : App.Superforms.Message> = [T] extends [T] ? () => SuperFormSnapshot<T, M> : never; type Restore<T extends Record<string, unknown>, M = App.Superforms.Message extends never ? any : App.Superforms.Message> = (snapshot: SuperFormSnapshot<T, M>) => void; export type SuperForm<T extends Record<string, unknown>, M = App.Superforms.Message extends never ? any : App.Superforms.Message> = { form: SuperFormData<T>; formId: Writable<string>; errors: SuperFormErrors<T>; constraints: Writable<InputConstraints<T>>; message: Writable<M | undefined>; tainted: Writable<TaintedFields<T> | undefined>; submitting: Readable<boolean>; delayed: Readable<boolean>; timeout: Readable<boolean>; /** * @deprecated posted is inconsistent between server and client validation, and SPA mode. Will be removed in v3. Use a status message or return your own data in the form action to handle form post status. */ posted: Readable<boolean>; allErrors: Readable<{ path: string; messages: string[]; }[]>; options: T extends T ? FormOptions<T, M> : never; enhance: (el: HTMLFormElement, events?: SuperFormEvents<T, M>) => ReturnType<typeof kitEnhance>; isTainted: (path?: FormPath<T> | Record<string, unknown> | boolean | undefined) => boolean; reset: (options?: ResetOptions<T>) => void; submit: (submitter?: HTMLElement | Event | EventTarget | null) => void; capture: Capture<T, M>; restore: T extends T ? Restore<T, M> : never; validate: <Out extends Partial<T> = T, Path extends FormPathLeaves<T> = FormPathLeaves<T>, In extends Record<string, unknown> = Record<string, unknown>>(path: Path, opts?: ValidateOptions<FormPathType<T, Path>, Out, In>) => Promise<string[] | undefined>; validateForm: <Out extends Partial<T> = T, In extends Record<string, unknown> = Record<string, unknown>>(opts?: { update?: boolean; schema?: ValidationAdapter<Out, In>; focusOnError?: boolean; }) => Promise<SuperFormValidated<T, M, In>>; }; export type ValidateOptions<Value, Out extends Record<string, unknown>, In extends Record<string, unknown>> = Partial<{ value: Value; update: boolean | 'errors' | 'value'; taint: TaintOption; errors: string | string[]; schema: ValidationAdapter<Out, In>; }>; export type ChangeEvent<T extends Record<string, unknown>> = { path: FormPath<T>; paths: FormPath<T>[]; formElement: HTMLFormElement; target: Element; set: <Path extends FormPath<T>>(path: Path, value: FormPathType<T, Path>, options?: ProxyOptions) => void; get: <Path extends FormPath<T>>(path: Path) => FormPathType<T, Path>; } | { target: undefined; paths: FormPath<T>[]; set: <Path extends FormPath<T>>(path: Path, value: FormPathType<T, Path>, options?: ProxyOptions) => void; get: <Path extends FormPath<T>>(path: Path) => FormPathType<T, Path>; }; /** * Initializes a SvelteKit form, for convenient handling of values, errors and sumbitting data. * @param {SuperValidated} form Usually data.form from PageData or defaults, but can also be an object with default values, but then constraints won't be available. * @param {FormOptions} formOptions Configuration for the form. * @returns {SuperForm} A SuperForm object that can be used in a Svelte component. * @DCI-context */ export declare function superForm<T extends Record<string, unknown> = Record<string, unknown>, M = App.Superforms.Message extends never ? any : App.Superforms.Message, In extends Record<string, unknown> = T>(form: SuperValidated<T, M, In> | T, formOptions?: FormOptions<T, M, In>): SuperForm<T, M>; export {};