Skip to Content

Plugin Shape

Custom plugins implement OberonPlugin:

export type OberonPlugin = ({ phase }: { phase: "bootstrap" | "runtime" }) => { name: string version?: string disabled?: boolean adapter?: OberonPluginAdapterHooks handlers?: Record<string, (adapter: OberonAdapter) => OberonHandler> bootstrap?: (context: { adapter: OberonAdapter }) => Promise<void> }

Input

The plugin function receives the current phase. It returns a declarative definition; executable hooks receive adapters only after composition is complete.

That means a plugin can:

  • contribute different definitions during Runtime and Bootstrap composition
  • wrap an Adapter method through next without losing later capabilities
  • use the final composed Adapter from Adapter hooks, Bootstrap hooks, and Handler hooks

Return value

name

Required. Included in the plugin metadata reported by the Oberon runtime.

version

Optional. Included in plugin version metadata.

disabled

Optional. When true, the plugin is recorded in plugin metadata but its adapter and handlers are not merged.

adapter

Optional. Adapter hooks are factories that receive { getAdapter, next } once and return a method with the corresponding OberonPluginAdapter signature. Call getAdapter() only from the returned method; it throws while factories are still composing. Only provide methods your plugin owns or wraps.

handlers

Optional. A map of route segment to handler factory. Each factory receives the final adapter and is invoked once during Runtime composition.

bootstrap

Optional. An ordered lifecycle task receiving the final Bootstrap Adapter.

Merge behavior

Plugin definitions are collected in configured order before executable hooks run.

  • returned handlers are merged into the accumulated handler map
  • later adapter hooks are outermost and call next to continue the earlier chain
  • omitting next replaces every earlier implementation for that method
  • every executing hook resolves the same final augmented Adapter, regardless of Plugin position
  • Bootstrap hooks run sequentially in configured order
  • disabled plugins contribute version metadata only

Minimal shape

import type { OberonPlugin } from "@oberoncms/core" export const plugin: OberonPlugin = () => ({ name: "my-plugin", })

Plugin with adapter and handlers

import type { OberonPlugin } from "@oberoncms/core" export const plugin: OberonPlugin = () => ({ name: "my-plugin", adapter: { signOut: ({ next }) => async () => { await next() }, }, handlers: {}, })

Use Adapter Hooks for the adapter surface and Handler Hooks for route handlers.

Last updated on