UNPKG

@sveltejs/kit

Version:

SvelteKit is the fastest way to build Svelte apps

203 lines (185 loc) • 9.33 kB
import { StandardSchemaV1 } from '@standard-schema/spec'; import { NavigationEvent, RequestEvent } from '@sveltejs/kit'; import { MaybePromise } from 'types'; export * from './index.js'; /** * The [`handle`](https://svelte.dev/docs/kit/hooks#handle) hook runs every time the SvelteKit server receives a [request](https://svelte.dev/docs/kit/web-standards#Fetch-APIs-Request) and * determines the [response](https://svelte.dev/docs/kit/web-standards#Fetch-APIs-Response). * It receives an `event` object representing the request and a function called `resolve`, which renders the route and generates a `Response`. * This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example). */ export type Handle = (input: { event: RequestEvent; resolve: (event: RequestEvent, opts?: ResolveOptions) => Promise<Response>; }) => MaybePromise<Response>; type CaughtErrorMap = { app: App.Error; framework: { status: number; message: string }; unknown: unknown; }; type ValidationCaughtError<Issue extends StandardSchemaV1.Issue> = { kind: 'validation'; error: { status: number; message: string }; issues: Issue[]; }; /** * The error passed to the [`handleError`](https://svelte.dev/docs/kit/hooks#handleError) hooks. * Use the `kind` discriminant to distinguish errors from your app (thrown with the * [`error`](https://svelte.dev/docs/kit/errors#App-errors) helper), errors generated by * SvelteKit itself (such as 404s), validation errors, and unknown errors (thrown by your code, * or code it calls). */ export type CaughtError<Issue extends StandardSchemaV1.Issue = StandardSchemaV1.Issue> = | { [Kind in keyof CaughtErrorMap]: { /** Identifies the category and origin of the error */ kind: Kind; /** The caught error. Its type depends on `kind` */ error: CaughtErrorMap[Kind]; /** Only present for validation errors */ issues?: undefined; }; }[keyof CaughtErrorMap] | ValidationCaughtError<Issue>; /** The error passed to the client-side `handleError` hook. */ export type ClientCaughtError = Exclude<CaughtError, { kind: 'validation' }>; /** * The server-side [`handleError`](https://svelte.dev/docs/kit/hooks#handleError) hook runs for every error thrown while responding to a request, except redirects. * * The `kind` property discriminates between _app_ errors (thrown with the [`error`](https://svelte.dev/docs/kit/errors#App-errors) helper), * _framework_ errors (generated by SvelteKit itself, such as 404s), _validation_ errors (caused by invalid remote function arguments) * and _unknown_ errors (thrown by your code, or code it calls). * * The hook returns an object matching `App.Error`, in which `status` and `message` are optional — return them only to * override the defaults. Omitted properties are inherited from the caught error: the body passed to `error(...)` for app errors, * the status and safe message for framework and validation errors, and `500`/`'Internal Error'` for unknown errors. Return nothing to * keep the defaults entirely (if you augment `App.Error` with required properties, you must return those). * * Make sure that this function _never_ throws an error. */ export type HandleServerError<Issue extends StandardSchemaV1.Issue = StandardSchemaV1.Issue> = ( input: CaughtError<Issue> & { event: RequestEvent } ) => MaybePromise<AppErrorWithOptionalDefaults | VoidIfNoRequiredAppErrorProperties>; /** * The client-side [`handleError`](https://svelte.dev/docs/kit/hooks#handleError) hook runs for every error thrown while navigating, except redirects. * Errors that were already transformed by the server-side hook are not passed to it a second time. * * The `kind` property discriminates between _app_ errors (thrown with the [`error`](https://svelte.dev/docs/kit/errors#App-errors) helper), * _framework_ errors (generated by SvelteKit itself, such as 404s) and _unknown_ errors (thrown by your code, or code it calls). * * The hook returns an object matching `App.Error`, in which `status` and `message` are optional — return them only to * override the defaults. Omitted properties are inherited from the caught error: the body passed to `error(...)` for app errors, * the status and safe message for framework errors, and `500`/`'Internal Error'` for unknown errors. Return nothing to * keep the defaults entirely (if you augment `App.Error` with required properties, you must return those). * * Make sure that this function _never_ throws an error. */ export type HandleClientError = ( input: ClientCaughtError & { event: NavigationEvent } ) => MaybePromise<AppErrorWithOptionalDefaults | VoidIfNoRequiredAppErrorProperties>; /** * The [`handleFetch`](https://svelte.dev/docs/kit/hooks#handleFetch) hook allows you to modify (or replace) the result of an [`event.fetch`](https://svelte.dev/docs/kit/load#Making-fetch-requests) call that runs on the server (or during prerendering) inside an endpoint, `load`, `action`, `handle`, `handleError` or `reroute`. */ export type HandleFetch = (input: { event: RequestEvent; request: Request; fetch: typeof fetch; }) => MaybePromise<Response>; /** * The [`init`](https://svelte.dev/docs/kit/hooks#init) will be invoked before the server responds to its first request * @since 2.10.0 */ export type ServerInit = () => MaybePromise<void>; /** * The [`init`](https://svelte.dev/docs/kit/hooks#init) will be invoked once the app starts in the browser * @since 2.10.0 */ export type ClientInit = () => MaybePromise<void>; /** * The [`reroute`](https://svelte.dev/docs/kit/hooks#reroute) hook allows you to modify the URL before it is used to determine which route to render. * @since 2.3.0 */ export type Reroute = (event: { url: URL; fetch: typeof fetch }) => MaybePromise<void | string>; /** * The [`transport`](https://svelte.dev/docs/kit/hooks#transport) hook allows you to transport custom types across the server/client boundary. * * Each transporter has a pair of `encode` and `decode` functions. On the server, `encode` determines whether a value is an instance of the custom type and, if so, returns a non-falsy encoding of the value which can be an object or an array (or `false` otherwise). * * In the browser, `decode` turns the encoding back into an instance of the custom type. * * ```ts * import type { Transport } from '@sveltejs/kit/hooks'; * * declare class MyCustomType { * data: any * } * * // hooks.js * export const transport: Transport = { * MyCustomType: { * encode: (value) => value instanceof MyCustomType && [value.data], * decode: ([data]) => new MyCustomType(data) * } * }; * ``` * @since 2.11.0 */ export type Transport = Record<string, Transporter>; /** * A member of the [`transport`](https://svelte.dev/docs/kit/hooks#transport) hook. */ export interface Transporter< T = any, U = any /* minus falsy values, but we can't properly express that */ > { encode: (value: T) => false | U; decode: (data: U) => T; } export interface ResolveOptions { /** * Applies custom transforms to HTML. If `done` is true, it's the final chunk. Chunks are not guaranteed to be well-formed HTML * (they could include an element's opening tag but not its closing tag, for example) * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise<string | undefined>; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. * @param name header name * @param value header value */ filterSerializedResponseHeaders?: (name: string, value: string) => boolean; /** * Determines which files should be preloaded. Files are preloaded via `<link>` tags added to the * `<head>` tag; if `output.linkHeaderPreload` is enabled, dynamically rendered pages use the * [`Link` response header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link) instead. * By default, `js` and `css` files will be preloaded. * * For `font` files, `input` also has a `filename` property, the source file's pathname relative * to the project root, so that a filter can match on it instead of the hashed path. `js` and * `css` files are bundled and have no single source file name. * @param input the type of the file and its path */ preload?: ( input: | { type: 'css' | 'js' | 'asset'; path: string } | { type: 'font'; path: string; filename: string } ) => boolean; } type AppErrorWithOptionalDefaults = Omit<App.Error, 'status' | 'message'> & { status?: App.Error['status']; message?: App.Error['message']; }; /** * `void` is only a valid `handleError` return when `App.Error` adds no required properties * beyond `status` and `message` — both of which are optional in the return, since they default * to those of the caught error. If `App.Error` is augmented with required properties, the hook * must return them, so returning nothing becomes a type error. */ type VoidIfNoRequiredAppErrorProperties = { status: number; message: string; } extends App.Error ? void : never;