546 lines
16 KiB
TypeScript
546 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;
|
|
/**
|
|
* Maximum time (ms) a page's server render may take before it is
|
|
* aborted and answered with a 500. Defaults to 30000.
|
|
*/
|
|
ssr_render_timeout_ms?: number;
|
|
};
|
|
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;
|
|
};
|
|
};
|
|
};
|