Files
bunext/dist/types/index.d.ts
T

541 lines
16 KiB
TypeScript

import type { MatchedRoute, Server, WebSocketHandler } from "bun";
import type { DetailedHTMLProps, FC, HtmlHTMLAttributes, PropsWithChildren } from "react";
export type ServerProps = {
params: Record<string, string>;
searchParams: Record<string, string>;
headers: Headers;
cookies: Record<string, string>;
body: any;
method: string;
url: string;
pathname: string;
query: Record<string, string>;
search: string;
hash: string;
};
export type StaticProps = {
params: Record<string, string>;
searchParams: Record<string, string>;
headers: Headers;
cookies: Record<string, string>;
body: any;
method: string;
url: string;
pathname: string;
query: Record<string, string>;
search: string;
hash: string;
};
export type StaticPaths = string[];
export type StaticParams = Record<string, string>;
export type PageModule = {
component: React.ComponentType<any>;
serverProps: ServerProps;
staticProps: StaticProps;
staticPaths: StaticPaths;
staticParams: StaticParams;
};
export type BunextConfig = {
dist_dir?: string;
assets_prefix?: string;
origin?: string;
global_vars?: {
[k: string]: any;
};
port?: number;
development?: boolean;
middleware?: (params: BunextConfigMiddlewareParams) => Promise<Response | Request | undefined> | Response | Request | undefined;
default_cache_expiry?: number;
/**
* Maximum number of cached pages kept on disk. New pages are not
* cached once this is reached. Defaults to 1000.
*/
max_cache_entries?: number;
/**
* By default, pages are not written to the cache when the request
* carries a `Cookie` or `Authorization` header, so one user's page is
* never served to everyone. Set this to `true` only if your cached
* pages never render per-user content.
*/
cache_credentialed_requests?: boolean;
/**
* Trust the `X-Forwarded-Proto` header (set this when running behind a
* reverse proxy that sets it). Defaults to `false`.
*/
trust_proxy?: boolean;
websocket?: WebSocketHandler<any>;
server_options?: Omit<Bun.Serve.Options<any>, "fetch" | "routes">;
/**
* These are patterns in the pages to exclude
* from the router
*/
pages_exclude_patterns?: RegExp[];
max_logs?: number;
/**
* Patterns to exclude from the SSR bundler. This is
* required for modules that aren't compatible with esbuild
* bundler. Eg. `sqlite-vec`
*/
ssr_compiler_excludes?: string[];
/**
* Patterns to exclude from the Main page bundler. This is
* required for modules that aren't compatible with esbuild
* bundler for the browser. Eg. `react/jsx-dev-runtime`
*/
page_compiler_excludes?: string[];
/**
* Patterns to exclude from the watcher. Eg. `./src/server.ts`
* or `\*.test.ts\`. It should either be a file path (relative or
* absolute), or a RegEx pattern.
*/
exclude_watch_patterns?: (string | RegExp)[];
/**
* Public environment variables to be passed to the client
*/
public_envs?: Record<string, string>;
/**
* Options for the `bunext sitemap` command
*/
sitemap?: BunextSitemapConfig;
/**
* Options for the robots.txt written by `bunext sitemap`. Set to
* `false` to skip generating it.
*/
robots?: BunextRobotsConfig | false;
/**
* Keep the whole site out of search engines, e.g. for preview
* deployments. Every response gets `X-Robots-Tag: noindex, nofollow`,
* pages get a matching robots meta tag (overriding `meta.robots`), and
* `/robots.txt` disallows all crawlers regardless of `public/robots.txt`.
*/
disable_seo?: boolean;
};
export type BunextConfigMiddlewareParams = {
req: Request;
url: URL;
};
export type GetRouteReturn = {
match: MatchedRoute;
module: PageModule;
component: React.ComponentType<any>;
serverProps: ServerProps;
staticProps: StaticProps;
staticPaths: StaticPaths;
staticParams: StaticParams;
};
export type BunxRouteParams = {
req: Request;
url: URL;
body?: any;
query?: any;
/**
* Intercept and Transform the response object
*/
res_transform?: (res: Response) => Promise<Response> | Response;
server?: Server<any>;
};
export interface PostInsertReturn {
fieldCount?: number;
affectedRows?: number;
insertId?: number;
serverStatus?: number;
warningCount?: number;
message?: string;
protocol41?: boolean;
changedRows?: number;
}
export type APIResponseObject<T extends {
[k: string]: any;
} = {
[k: string]: any;
}> = {
success: boolean;
payload?: T[] | null;
singleRes?: T | null;
stringRes?: string | null;
numberRes?: number | null;
postInsertReturn?: PostInsertReturn | null;
payloadBase64?: string;
payloadThumbnailBase64?: string;
payloadURL?: string;
payloadThumbnailURL?: string;
error?: any;
msg?: string;
queryObject?: any;
countQueryObject?: any;
status?: number;
count?: number;
errors?: any[];
debug?: any;
batchPayload?: any[][] | null;
errorData?: any;
token?: string;
csrf?: string;
cookieNames?: any;
key?: string;
userId?: string | number;
code?: string;
createdAt?: number;
email?: string;
requestOptions?: any;
logoutUser?: boolean;
redirect?: string;
};
export type BunextServerRouteConfig = {
max_request_body_mb?: number;
};
export type LivePageDistGenParams = {
component?: FC;
pageProps?: any;
module?: BunextPageModule;
root_module?: BunextRootModule;
bundledMap?: BundlerCTXMap;
routeParams?: BunxRouteParams;
debug?: boolean;
};
export type BunextPageHeadFCProps = {
serverRes: BunextPageModuleServerReturn;
ctx?: BunxRouteParams;
};
export type BunextPageModule = {
default: FC<any>;
meta?: BunextPageModuleMeta | BunextPageModuleMetaFn;
Head?: FC<BunextPageHeadFCProps>;
config?: BunextRouteConfig;
html_props?: BunextHTMLProps;
};
export type BunextPageServerModule = {
default?: BunextPageServerFn;
server?: BunextPageServerFn;
sitemap?: BunextPageSitemapFn;
};
/**
* Returns the sitemap entries for a page. Required for dynamic routes
* (`[slug]`) to appear in the sitemap. On a static page, the returned
* entries replace the page's default entry.
*/
export type BunextPageSitemapFn = (params: {
/**
* The page's route pattern, e.g. `/blog/[slug]`
*/
route: string;
}) => BunextSitemapAdditionalPaths | Promise<BunextSitemapAdditionalPaths>;
export type BunextHTMLProps = DetailedHTMLProps<HtmlHTMLAttributes<HTMLHtmlElement>, HTMLHtmlElement>;
export type BunextPageModuleMetaFn = (params: {
ctx: BunxRouteParams;
serverRes?: BunextPageModuleServerReturn;
}) => Promise<BunextPageModuleMeta>;
export type BunextPageModuleMeta = {
title?: string;
description?: string;
keywords?: string | string[];
author?: string;
robots?: string;
canonical?: string;
themeColor?: string;
og?: BunextPageModuleMetaOG;
twitter?: BunextPageModuleMetaTwitter;
};
export type BunextPageModuleMetaOG = {
title?: string;
description?: string;
image?: string;
url?: string;
type?: string;
siteName?: string;
locale?: string;
};
export type BunextPageModuleMetaTwitter = {
card?: "summary" | "summary_large_image" | "app" | "player";
title?: string;
description?: string;
image?: string;
site?: string;
creator?: string;
};
export type BunextPageServerFn<T extends {
[k: string]: any;
} = {
[k: string]: any;
}> = (ctx: Omit<BunxRouteParams, "body"> & {
props?: T;
}) => Promise<BunextPageModuleServerReturn<T>>;
export type BunextRouteConfig = {
/**
* Whether to cache the current page
*/
cachePage?: BunextCachePageType;
/**
* Expiry time of the cache in seconds
*/
cacheExpiry?: number;
};
export type BunextPageModuleServerReturn<T extends {
[k: string]: any;
} = {
[k: string]: any;
}, Q extends {
[k: string]: any;
} = {
[k: string]: any;
}> = {
props?: T;
query?: Q;
redirect?: BunextPageModuleServerRedirect;
response_options?: ResponseInit;
/**
* Whether to cache the current page
*/
cache_page?: BunextCachePageType;
/**
* Expiry time of the cache in seconds
*/
cache_expiry?: number;
url?: BunextPageModuleServerReturnURLObject;
error?: string;
res_transform?: (res: Response) => Promise<Response> | Response;
};
export type BunextCachePageType = boolean | ((params: {
ctx: Omit<BunxRouteParams, "body">;
serverRes?: BunextPageModuleServerReturn;
}) => Promise<boolean> | boolean);
export type BunextPageProps<T extends {
[k: string]: any;
} = {
[k: string]: any;
}, Q extends {
[k: string]: any;
} = {
[k: string]: any;
}> = BunextPageModuleServerReturn<T, Q>;
export type BunextPageModuleServerReturnURLObject = {
hash: string;
host: string;
hostname: string;
href: string;
origin: string;
password: string;
pathname: string;
port: string;
protocol: string;
search: string;
searchParams: Record<string, string>;
username: string;
};
export type BunextPageModuleServerRedirect = {
destination: string;
permanent?: boolean;
status_code?: number;
};
export type BunextPageModuleMetadata = {
title?: string;
description?: string;
};
export type GrabPageComponentRes = {
component?: FC;
serverRes?: BunextPageModuleServerReturn;
routeParams?: BunxRouteParams;
bundledMap?: BundlerCTXMap;
module?: BunextPageModule;
root_module?: BunextRootModule;
debug?: boolean;
success?: boolean;
};
export type BunextRootModule = BunextPageModule;
export type GrabPageReactBundledComponentRes = {
component?: FC;
server_res?: BunextPageModuleServerReturn;
tsx?: string;
/**
* The page's own exports (`meta`, `Head`, `config`, ...), re-exported
* from the SSR bundle so they share its fresh module graph.
*/
page_module?: BunextPageModule;
root_module?: BunextPageModule;
};
export type PageFiles = {
local_path: string;
url_path: string;
file_name: string;
};
export type BundlerCTXMap = {
path: string;
hash: string;
type: string;
entrypoint: string;
local_path: string;
url_path: string;
file_name: string;
css_path?: string;
};
export type GlobalHMRControllerObject = {
controller: ReadableStreamDefaultController<string>;
page_url: string;
target_map?: BundlerCTXMap;
page_props?: any;
page_reloaded?: boolean;
page_cookie?: string | null;
};
export type BunextCacheFileMeta = {
date_created: number;
paradigm: "html" | "json";
expiry_seconds?: number;
};
export type BunextRootComponentProps = PropsWithChildren & BunextPageProps;
export type GrabTSXModuleSingleParams = {
tsx: string;
page_file_path: string;
};
export type GrabTSXModuleBatchParams = {
tsx_map: GrabTSXModuleBatchMap[];
};
export type GrabTSXModuleBatchMap = {
tsx: string;
page_file_path: string;
};
export type BunextAPIRouteJSONRes = {
bunext_api_route_res_options?: ResponseInit;
bunext_api_route_res_transform_fn?: (res: Response) => Promise<Response> | Response;
} & {
[k: string]: any;
};
export type BunextAPIRouteHandlerObjectReturn<T> = Response | (T & Pick<BunextAPIRouteJSONRes, "bunext_api_route_res_options" | "bunext_api_route_res_transform_fn">);
export type BunextAPIRouteHandler<T extends BunextAPIRouteJSONRes = {
[k: string]: any;
}> = (params: BunxRouteParams) => Promise<BunextAPIRouteHandlerObjectReturn<T>> | Response | BunextAPIRouteHandlerObjectReturn<T>;
export type BunSpawnOptions = Bun.SpawnOptions.SpawnOptions<"inherit", "inherit", "inherit"> & {
cmd: string[];
};
export type BuildDataType = {
build_id: string;
build_date_unix: number;
build_date: string;
};
export type BunextSitemapChangeFreq = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
export type BunextSitemapEntry = {
/**
* URL path (e.g. `/blog/my-post`) or absolute URL.
*/
path: string;
lastmod?: Date | string;
changefreq?: BunextSitemapChangeFreq;
/**
* Between `0.0` and `1.0`.
*/
priority?: number;
};
export type BunextSitemapAdditionalPaths = (string | BunextSitemapEntry)[];
export type BunextGenerateSitemapParams = {
/**
* Base URL prepended to every path. Defaults to `config.origin`,
* falling back to `http://localhost:<port>`.
*/
origin?: string;
/**
* Paths to leave out. A string matches a path exactly, or a whole
* subtree when it ends with `/*` (e.g. `/admin/*`). A RegExp is
* tested against the path.
*/
exclude?: (string | RegExp)[];
/**
* Extra entries, typically concrete URLs for dynamic routes
* (`[slug]`), which cannot be discovered from the file system. Can
* also be a function (sync or async) returning them, e.g. to load
* them from a database.
*/
additional_paths?: BunextSitemapAdditionalPaths | (() => BunextSitemapAdditionalPaths | Promise<BunextSitemapAdditionalPaths>);
/**
* Fall back to each page file's modification time as `lastmod` when
* the build record has no date for it. Defaults to `false`: checkouts
* reset modification times, so they are rarely meaningful.
*/
use_file_lastmod?: boolean;
/**
* `lastmod` for entries that have no other date
*/
default_lastmod?: Date | string;
/**
* Page last-modified record written by `bunext build`, relative to the
* project root. Defaults to `.bunext/page-lastmod.json`. Point it at a
* cached or committed location when builds start from a fresh checkout.
*/
lastmod_file?: string;
/**
* Append a trailing slash to every non-root path. Defaults to `false`.
*/
trailing_slash?: boolean;
default_changefreq?: BunextSitemapChangeFreq;
default_priority?: number;
};
export type BunextSitemapConfig = BunextGenerateSitemapParams & {
/**
* Maximum URLs per sitemap file. Above this, `bunext sitemap` writes
* chunk files to `chunks_dir` and makes sitemap.xml a sitemap index
* referencing them. Defaults to 10,000; capped at 50,000, the protocol
* limit. Chunks are also split at 50MB.
*/
chunk_size?: number;
/**
* Directory for sitemap chunk files, relative to the project root.
* Must be inside `public/` so the files are served. Defaults to
* `public/sitemap-chunks`.
*/
chunks_dir?: string;
/**
* Output file, relative to the project root. Defaults to
* `public/sitemap.xml`, which is served at `/sitemap.xml`.
*/
output?: string;
};
export type BunextRobotsRule = {
/**
* One or more crawler names, e.g. `*` or `["GPTBot", "CCBot"]`
*/
user_agent: string | string[];
allow?: string[];
disallow?: string[];
/**
* Seconds between requests. Not supported by every crawler.
*/
crawl_delay?: number;
};
export type BunextGenerateRobotsTxtParams = {
/**
* Base URL used to turn relative `sitemaps` paths into absolute URLs.
* Defaults to `config.origin`, falling back to `http://localhost:<port>`.
*/
origin?: string;
/**
* Defaults to allowing every crawler everywhere.
*/
rules?: BunextRobotsRule[];
/**
* Sitemap URLs or paths, each written as a `Sitemap:` line.
*/
sitemaps?: string[];
/**
* Block every crawler from the whole site, ignoring `rules` and
* `sitemaps`. Useful for staging deployments.
*/
disallow_all?: boolean;
};
export type BunextRobotsConfig = BunextGenerateRobotsTxtParams & {
/**
* Output file, relative to the project root. Defaults to
* `public/robots.txt`, which is served at `/robots.txt`.
*/
output?: string;
};
/**
* Written by `bunext build`. Keyed by page path relative to the project
* root. `lastmod` is the build date at which `fingerprint` last changed.
*/
export type BunextPageLastmodRecord = {
pages: {
[local_path: string]: {
fingerprint: string;
lastmod: string;
};
};
};