tool

package
v0.11.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package tool defines the public contract every tool module must satisfy. Downstream projects implement Module to register a tool with wick via wick/app.RegisterTool.

A module exposes metadata via Meta() and wires its handlers via Register(r Router). Wick owns the HTTP mux, the page renderer, and the static-asset mount — the module only declares routes through the Router and reacts to requests via *Ctx.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func StaticHandler

func StaticHandler(prefix string, fsys fs.FS) http.Handler

StaticHandler serves files from fsys under the given URL prefix. Directory listings return 404 so embedded asset trees don't leak. Wick uses this internally for Router.Static; modules never call it directly.

func ValidateModules

func ValidateModules(modules []Module) error

ValidateModules is called by wick at boot. It checks that every module's Meta has the minimum required fields (Key, Name, Icon) and that no two modules share the same Key. A non-nil error means the process should refuse to start.

Path is derived by wick from Key ("/tools/{Key}") after validation; registrations must leave Tool.Path zero.

Types

type ConfigReader

type ConfigReader interface {
	GetOwned(owner, key string) string
	Missing(owner string) []string
}

ConfigReader is the narrow slice of the config service wick exposes to tool handlers. Scoping by owner happens in Ctx — handlers see only their own tool's values. Implementations live in internal/ configs; this interface keeps pkg/tool free of internal imports.

type Ctx

type Ctx struct {
	W http.ResponseWriter
	R *http.Request
	// contains filtered or unexported fields
}

Ctx is the per-request handle passed to every HandlerFunc. It bundles the raw http.ResponseWriter and *http.Request with wick-supplied helpers for the things a tool handler does constantly: read form values, decode JSON bodies, render HTML, write JSON, redirect.

Drop down to Ctx.W / Ctx.R when you need something a helper does not expose — the helpers are shortcuts, not a wall.

func NewCtx

func NewCtx(w http.ResponseWriter, r *http.Request, render RenderFunc, meta Tool, cfg ConfigReader) *Ctx

NewCtx is used by wick when mounting handlers. Modules never call it directly — they receive a *Ctx ready to use.

func (*Ctx) Base

func (c *Ctx) Base() string

Base returns the absolute mount path for this tool ("/tools/{Key}"). Use it for form actions, script src, and redirect targets so HTML works regardless of how many instances of the module are registered.

func (*Ctx) BindJSON

func (c *Ctx) BindJSON(v any) error

BindJSON decodes the request body into v. Returns the decoder error verbatim so the caller can surface it.

func (*Ctx) Cfg

func (c *Ctx) Cfg(key string) string

Cfg returns the current value of a Spec declared by this tool. The lookup is scoped to the active instance's Key — reading another tool's config requires CfgOf. Returns "" when the key is not declared or the config service is unavailable.

func (*Ctx) CfgBool

func (c *Ctx) CfgBool(key string) bool

CfgBool returns c.Cfg(key) parsed as bool. "true"/"1"/"yes"/"on" (case-insensitive) count as true; anything else is false.

func (*Ctx) CfgInt

func (c *Ctx) CfgInt(key string) int

CfgInt returns c.Cfg(key) parsed as int. Unparseable or empty values return 0 — handlers that need to distinguish "unset" from "zero" should mark the field Required and check c.Missing() first.

func (*Ctx) CfgOf

func (c *Ctx) CfgOf(owner, key string) string

CfgOf reads a config value from another owner (another tool or a job key). Intentionally verbose — reserved for cross-tool integrations that need a neighbor's endpoint or shared identifier. Prefer Cfg for the common case.

func (*Ctx) Context

func (c *Ctx) Context() context.Context

Context is a shortcut for c.R.Context(); use it for cancellation- aware calls into services and repositories.

func (*Ctx) Error

func (c *Ctx) Error(status int, msg string)

Error writes an error response with the given status code and message. Messages are plain text; use JSON for structured errors.

func (*Ctx) Form

func (c *Ctx) Form(key string) string

Form returns r.FormValue(key). Works for both url-encoded bodies and multipart forms. Empty string when the key is missing.

func (*Ctx) HTML

func (c *Ctx) HTML(body templ.Component)

HTML renders body inside wick's page shell and writes the full HTML response. Use for any tool page that lives under /tools/...

func (*Ctx) JSON

func (c *Ctx) JSON(status int, v any)

JSON writes v as application/json with the given status code.

func (*Ctx) Meta

func (c *Ctx) Meta() Tool

Meta returns the tool.Tool this route was mounted under. Handlers use it to read display metadata (Name, Icon) or ExternalURL without threading anything through closures.

func (*Ctx) Missing

func (c *Ctx) Missing() []string

Missing returns the names of Required Specs this tool declared that have no stored value yet. Handlers call it at the top of a request to decide whether to render the real view or a "setup required" banner. Returns nil when nothing is required or the config service is unavailable.

func (*Ctx) NotFound

func (c *Ctx) NotFound()

NotFound writes a 404 with no body.

func (*Ctx) PathValue

func (c *Ctx) PathValue(key string) string

PathValue returns a Go 1.22+ mux path parameter (e.g. "/items/{id}").

func (*Ctx) Query

func (c *Ctx) Query(key string) string

Query returns the URL query value for key.

func (*Ctx) Redirect

func (c *Ctx) Redirect(url string, code int)

Redirect issues an HTTP redirect. Code is typically http.StatusFound (302) for user actions or http.StatusSeeOther (303) after a POST.

type DefaultTag

type DefaultTag struct {
	Name        string
	Description string
	IsGroup     bool
	IsFilter    bool
	IsSystem    bool
	SortOrder   int
}

DefaultTag is the spec used by Tool.DefaultTags to seed tags on startup.

IsSystem marks the tag as code-owned — see entity.Tag godoc for the admin-UI implications (cannot be assigned to users from the picker).

type HandlerFunc

type HandlerFunc func(c *Ctx)

HandlerFunc is the tool-side handler signature. A handler receives a *Ctx that exposes request helpers (Form, Query, BindJSON) and response helpers (HTML, JSON, Redirect). Write to Ctx.W only when a helper doesn't fit — the helpers handle the render shell, content types, and status codes for you.

type Module

type Module struct {
	Meta     Tool
	Configs  []entity.Config
	Register RegisterFunc
}

Module is the internal, fully-resolved registration record wick keeps for every tool. It is produced by app.RegisterTool from a meta, a typed Config value (reflected into Configs at register time), and a RegisterFunc — downstream code does not construct Module directly.

type RegisterFunc

type RegisterFunc func(r Router)

RegisterFunc wires a tool's routes on the Router wick passes in. It is the handler-side half of module registration — paired with a Tool meta and a typed Config struct at app.RegisterTool time.

Handlers declared inside RegisterFunc stay stateless: per-instance metadata is read via c.Meta(), runtime-editable config values via c.Cfg(...). There is no per-module struct to carry private state.

type RenderFunc

type RenderFunc func(c *Ctx, body templ.Component)

RenderFunc wraps a body fragment in wick's page shell (navbar, layout, theme) and writes the full HTML response. Wick injects it into *Ctx; modules call it indirectly via Ctx.HTML. The *Ctx hand- off lets the renderer reach c.Missing() / c.Meta() without extra threading from the router.

type Router

type Router interface {
	GET(path string, h HandlerFunc)
	POST(path string, h HandlerFunc)
	PUT(path string, h HandlerFunc)
	DELETE(path string, h HandlerFunc)
	PATCH(path string, h HandlerFunc)
	Static(prefix string, fsys fs.FS)
	// HandleRaw mounts a raw http.Handler at a subtree prefix relative
	// to the tool's /tools/{Key} base. The prefix must end with "/".
	// Use sparingly — only when the handler owns its own sub-routing
	// (e.g. a reverse-proxy that serves many paths under one mount).
	// fn receives the ConfigReader so callers can gate on runtime config.
	HandleRaw(prefix string, fn func(cfg ConfigReader) http.Handler)
	Meta() Tool
}

Router is the surface wick exposes to a module's Register method. Modules declare their HTTP routes through these Echo/Gin-style verb methods; wick owns the underlying mux, validates that no two modules claim the same `METHOD PATH`, and mounts each handler with the page renderer already injected into *Ctx.

Paths passed to GET/POST/... are relative to the meta's /tools/{Key} base; wick prefixes them at mount time. Static mounts a read-only fs.FS at prefix — typically "/static/" for the module's embed.FS of js/css assets. Directory listings are blocked.

Meta returns the tool.Tool currently being registered. Register is invoked once per Meta entry; use this when a handler needs the base URL (form actions, script src) or the tool's display metadata.

type Tool

type Tool struct {
	// Key is the path segment that identifies this instance. Must be
	// unique across every Tool returned by every module — wick derives
	// the mount path from it as "/tools/{Key}". Lowercase slug, no
	// slashes. Multi-instance modules emit one Tool per Key.
	Key         string `json:"key"`
	Name        string `json:"name"`
	Description string `json:"description"`
	// Icon is a short label (e.g. "Aa", "{}") shown inside the icon box.
	Icon string `json:"icon"`
	// Path is the fully resolved mount path ("/tools/{Key}"). Wick fills
	// this in at boot — modules must leave it zero.
	Path     string `json:"path"`
	Category string `json:"category,omitempty"`
	// DefaultVisibility is the visibility used when no DB override exists.
	// Defaults to VisibilityPrivate if not set.
	DefaultVisibility entity.ToolVisibility `json:"-"`
	// ExternalURL marks the tool as an external link. When set, the home
	// card and palette open this URL in a new tab instead of navigating
	// to Path. Direct hits to Path still resolve (the module redirects)
	// so the link can be shared, bookmarked, and gated by the visibility
	// middleware.
	ExternalURL string `json:"external_url,omitempty"`
	// DefaultTags are seeded on startup. Each tag is created globally by
	// name if missing (existing tags keep their flags untouched). The
	// tags are also linked to this tool on the *first* registration only
	// — once any tool_tag row exists for the tool path, the seed step
	// skips linking so an admin who unlinks a tag won't see it return on
	// the next restart.
	DefaultTags []DefaultTag `json:"-"`
	// FullScreen opts this tool into full-viewport layout: the ToolHeader
	// title bar is hidden, the content area expands edge-to-edge (no
	// max-w-container padding), and the tool owns its own internal
	// navigation. All other tools keep the standard constrained layout.
	FullScreen bool `json:"-"`
}

Tool describes a tool entry shown on the home page.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL