import type { RequestContext } from "./typegen/http/request.ts"; export * from "./typegen/http/index.ts"; export * from "./typegen/orm/index.ts"; export * from "./typegen/minify.ts"; export type { ViewPath, ViewProps, ViewPropsOf } from "./typegen/views.ts"; /** A file handled by a loader. */ export interface LoaderFile { /** Absolute path of the file. */ path: string; /** Path relative to the project root. */ relativePath: string; /** Raw content of the file. */ source: string; } /** Result of a loader. */ export interface LoadedFile { /** Data exposed to the application, e.g. frontmatter and rendered html. */ data: Record; /** Rendered representation, e.g. the compiled css or the markdown html. */ content?: string; } export interface Loader { /** Name of the loader, used in error messages. */ name: string; /** File extensions handled by the loader, e.g. `['.md']`. */ extensions: string[]; /** Loads a single file. */ load(file: LoaderFile): Promise | LoadedFile; } /** Options shared by all loaders. */ export interface LoaderOptions { /** Directory the loader scans, relative to the project root. */ dir?: string; } /** Configuration of the content collections. */ export interface CollectionConfig { /** Name of the collection, e.g. `notes`. */ name: string; /** Directory of the collection, relative to the project root. */ dir: string; /** Loader used to read the files of the collection, by name or inline. */ loader: Loader | string; /** Schema of the frontmatter, validated at load time. */ schema?: ContentSchema; } /** Schema of a content collection. */ export interface ContentSchema { /** Required frontmatter fields. */ required?: string[]; /** Allowed values of a field. */ enum?: Record; /** Maximum length of a string field. */ maxLength?: Record; } /** A single entry of a content collection. */ export interface CollectionEntry< Frontmatter extends Record = Record, > { /** Identifier of the entry, derived from the file name. */ id: string; /** Path of the file, relative to the project root. */ path: string; /** Parsed frontmatter. */ frontmatter: Frontmatter; /** Rendered body. */ body: string; /** Raw markdown source. */ content: string; } /** Minimal view registry handed to integration mounts. */ export interface MountableViews { /** Registers a named view component. */ component( name: string, component: { render: (props: unknown, context: unknown) => string | Promise }, ): unknown; } /** A self-contained unit an integration mounts into the application. */ export interface Mounts { /** Registers view components, e.g. the primitives of a theme. */ views?(views: MountableViews): void | Promise; /** Adds routes, e.g. assets, fonts and endpoints. */ routes?( route: (method: string, path: string, handler: (request: Request) => Response | Promise) => void, ): void | Promise; /** Served inline stylesheets by route. */ styles?: Record string | Promise)>; } /** Integration hook, called while the application is created. */ export interface Integration { /** Transforms a staged build asset. Promises run in configured order. */ transform?(asset: BuildAsset): BuildAsset | Promise; /** Analyzes a fully rendered page before the output is published. */ analyze?(page: { route: string; html: string }): unknown | Promise; /** Runs before routing, including raw integration endpoints. */ request?(context: RequestContext): void | Promise; /** Name of the integration. */ name: string; /** Called with the resolved configuration. */ setup?(context: IntegrationContext): void | Promise; /** Full-stack units mounted while the application boots. */ mounts?: Mounts[]; /** Called before the server starts serving requests. */ ready?(): void | Promise; } export interface BuildAsset { path: string; contentType: string; content: string | Uint8Array; } /** Context handed to an integration. */ export interface IntegrationContext { /** Resolved project configuration. */ config: ResolvedConfig; /** Adds a route to the application. */ route( method: string, path: string, handler: ( request: Request, context: RequestContext, ) => Promise | Response, ): void; /** Adds a loader to the project. */ loader(name: string, loader: Loader): void; } /** Adapter configuration, e.g. the port of the http server. */ export interface AdapterOptions { /** Port the server listens on. */ port?: number; /** Hostname the server binds to. */ hostname?: string; /** Name of the adapter, e.g. `server-bun`. */ name?: string; } /** Database configuration. */ export interface DatabaseOptions { /** Dialect of the database. */ dialect: "sqlite" | "postgres" | "d1"; /** Path of the sqlite file or the connection string of postgres. */ url?: string; /** Cloudflare D1 binding configuration. */ d1?: { accountId: string; databaseId: string; apiToken: string }; } /** Prerendering configuration. */ export interface PrerenderOptions { /** Routes rendered at build time. */ routes: string[]; /** Directory the html files are written to. */ outDir?: string; /** Writes every route, even when the handler answers with a redirect. */ fallback?: boolean; } /** Project configuration, as written in `ct.config.ts`. */ export interface MuddleConfig { /** Root directory of the project. */ root?: string; /** Server entry module, relative to the project root. Defaults to `index.ts`. */ entry?: string; /** Directory with the templates. */ views?: string; /** Directory with the components. */ components?: string; /** Directory with the markdown collections. */ content?: string; /** Directory with the structured css files. */ styles?: string; /** Directory with static assets. */ publicDir?: string; /** Directories scanned for templates, relative to the project root. */ viewRoots?: string[]; /** Loaders available to the content collections. */ loaders?: Record; /** Content collections of the project. */ collections?: CollectionConfig[]; /** Integrations of the project. */ integrations?: Integration[]; /** Prerendering configuration. */ prerender?: PrerenderOptions; /** Adapter used to serve the application. */ adapter?: AdapterOptions; /** Database configuration. */ database?: DatabaseOptions; /** Model files of the project, relative to the project root. */ tables?: string[]; /** Where the generated contracts are written to. */ typegen?: { out?: string }; } /** Configuration with every default applied. */ export interface ResolvedConfig extends MuddleConfig { root: string; views: string; components: string; content: string; styles: string; publicDir: string; viewRoots: string[]; loaders: Record; collections: CollectionConfig[]; integrations: Integration[]; } /** * Declares the configuration of a project. * * The helper only exists for the editor: it checks the configuration while * it is written in `ct.config.ts`. */ export function defineConfig(config: MuddleConfig): MuddleConfig { return config; }