From 273da5b4db479d2b90f4bd9010e789e426dea146 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 30 Mar 2026 22:22:02 +0200 Subject: [PATCH] feat(plugins): add example plugin Demonstrates all plugin capabilities: authenticated and unauthenticated routes, event listeners, and lifecycle hooks. Uses a shared singleton for factory functions so Init() state is available to route handlers. --- examples/plugins/example/main.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/plugins/example/main.go b/examples/plugins/example/main.go index f791f0b02..afb358b2f 100644 --- a/examples/plugins/example/main.go +++ b/examples/plugins/example/main.go @@ -92,7 +92,19 @@ func handleStatus(c *echo.Context) error { }) } -func NewPlugin() plugins.Plugin { return &ExamplePlugin{} } +// singleton ensures all factory functions return the same instance so that state +// initialized in Init() (e.g. event listeners, DB connections) is available to +// route handlers and other capabilities. +var singleton = &ExamplePlugin{} + +func NewPlugin() plugins.Plugin { return singleton } + +// Typed factory functions for Yaegi compatibility. +// Yaegi wraps return values per the declared return type, so sub-interface type +// assertions (Plugin -> AuthenticatedRouterPlugin) don't work. These typed +// factories ensure Yaegi wraps the value with the correct interface wrapper. +func NewAuthenticatedRouterPlugin() plugins.AuthenticatedRouterPlugin { return singleton } +func NewUnauthenticatedRouterPlugin() plugins.UnauthenticatedRouterPlugin { return singleton } type TestListener struct{}