@sveltejs/kit
Version:
SvelteKit is the fastest way to build Svelte apps
203 lines (185 loc) • 9.33 kB
TypeScript
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;