Types
Every type below is exported from clovejs.
Ctx and RuntimeCtx
interface Ctx {
readonly cache: CacheController
}
type RuntimeCtx = Ctx & Record<string, any>Ctx contains the built-in cache invalidation facade. Your project augments it through the generated .clove/types.d.ts, which declares one property per file in services/ and di/ — see Typed context.
RuntimeCtx is what handlers actually receive: the augmented interface plus arbitrary keys, so an un-generated or hand-attached value still type-checks.
Lifetime
type Lifetime = "singleton" | "session" | "request"See Values and lifetimes.
HttpMethod
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS"Route definitions widen this to HttpMethod | "ALL".
Routes
type RouteHandlerFn = (
req: CloveRequest,
res: CloveResponse,
ctx: RuntimeCtx,
) => unknown | Promise<unknown>interface RouteMeta {
/** Set false to disable the built-in JSON middleware for this route. */
json?: boolean
[key: string]: unknown
}interface Route {
method: HttpMethod | "ALL"
path: string
handler: RouteHandlerFn
meta: Readonly<RouteMeta>
cache?: Readonly<CachePolicy>
invalidates?: CacheInvalidation
/** Absolute path of the file this route came from. Used in error messages. */
file: string
}Route is what middlewares receive as route, and what app.routes.list() returns.
Middlewares
interface MiddlewareArgs {
route: Route
handler: { execute(): Promise<unknown> }
req: CloveRequest
res: CloveResponse
ctx: RuntimeCtx
}
type MiddlewareFn = (args: MiddlewareArgs) => unknown | Promise<unknown>Services and values
type ServiceFactory<M = any> = (
ctx: RuntimeCtx,
hooks: LifecycleHooks,
) => (M & ThisType<M>) | Promise<M & ThisType<M>>
type ValueFactory<T = any> = (ctx: RuntimeCtx, hooks: LifecycleHooks) => T
interface DiSpec<T = any> {
lifetime: Lifetime
value: T | ValueFactory<T>
}
interface LifecycleHooks {
onDestroy(fn: () => void | Promise<void>): void
readonly trigger?: Trigger
}
type Trigger =
| { kind: "http"; req: CloveRequest; res: CloveResponse }
| { kind: "ws"; req: CloveRequest }
| { kind: "mcp"; method: string }
| { kind: "delivery"; bus: string; channel: string; subscription: string; consumer: string }M is the resolved service value. The ThisType<M> woven into the awaited type keeps this typed as M inside the factory. Consumers unwrap the definition with Awaited<M> (which is just M).
trigger is what opened the scope a factory's value lives in — see Knowing what opened the scope. It is undefined for singleton and session factories, which outlive any single unit of work.
WebSockets
interface WsArgs {
onMessage(fn: (msg: string | Buffer) => void | Promise<void>): void
onClose(fn: () => void | Promise<void>): void
onDestroy(fn: () => void | Promise<void>): void
send(data: string | Buffer | object): void
close(code?: number, reason?: string): void
ctx: RuntimeCtx
req: CloveRequest
params: Record<string, string>
}
type WsHandlerFn = (args: WsArgs) => void | Promise<void>Definition types
The values the wrappers return. You rarely name these directly — they appear in typeof import(...) positions inside generated declarations.
| Type | Produced by |
|---|---|
RouteDefinition | get(), post(), … |
MiddlewareDefinition | middleware() |
ServiceDefinition<T> | service() |
DiDefinition<T> | di() |
WsDefinition | ws() |
Type helpers
type CloveService<T> // the awaited value a service() definition resolves to
type CloveDi<T> // the value a di() definition resolves to, factory or notUsed by .clove/types.d.ts; available to you for the same purpose.
Runtime and server types
| Type | Description |
|---|---|
BootstrapOptions | Options for bootstrap() |
AppOptions | Options for createApp() and engine() |
Clove | What bootstrap() resolves to: app, server, port, host, url, close() |
CloveEngine | What engine() resolves to — see Express interop |
SessionStore | The get / set / touch / destroy contract |
CookieOptions | Options for res.cookie() |
Logger, LogLevel | The logger interface and its levels |