Documentation
¶
Index ¶
- Constants
- Variables
- func AssetHandler() http.Handler
- func CacheHandler(hash string, next http.Handler) http.Handler
- func CreateUsernameFromBech32(username string) string
- func GetClientErrorStatusView(_ *weburl.GnoURL, err error, height int64) (int, *components.View)
- func NewDefaultChromaOptions() []chromahtml.Option
- func NewDefaultGoldmarkOptions() []goldmark.Option
- func NewRouter(logger *slog.Logger, cfg *AppConfig) (http.Handler, error)
- func NoCacheHandler(next http.Handler) http.Handler
- func RedirectMiddleware(next http.Handler, meta StaticMetadata) http.Handler
- type AliasKind
- type AliasTarget
- type AppConfig
- type ClientAdapter
- type FileMeta
- type HTMLRenderer
- func (r *HTMLRenderer) RenderDocumentation(w io.Writer, src []byte) error
- func (r *HTMLRenderer) RenderRealm(w io.Writer, u *weburl.GnoURL, src []byte, ctx RealmRenderContext) (md.Toc, error)
- func (r *HTMLRenderer) RenderSource(w io.Writer, name string, src []byte) error
- func (r *HTMLRenderer) WriteChromaCSS(w io.Writer) error
- type HTTPHandler
- func (h *HTTPHandler) Get(w http.ResponseWriter, r *http.Request)
- func (h *HTTPHandler) GetDirectoryView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
- func (h *HTTPHandler) GetHelpView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
- func (h *HTTPHandler) GetMarkdownView(gnourl *weburl.GnoURL, mdContent string) (int, *components.View)
- func (h *HTTPHandler) GetPackageView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
- func (h *HTTPHandler) GetPathsListView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
- func (h *HTTPHandler) GetRealmView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
- func (h *HTTPHandler) GetSourceView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
- func (h *HTTPHandler) GetUserView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
- func (h *HTTPHandler) Post(w http.ResponseWriter, r *http.Request)
- func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (h *HTTPHandler) ServeSourceDownload(ctx context.Context, gnourl *weburl.GnoURL, w http.ResponseWriter, ...)
- type HTTPHandlerConfig
- type MockClient
- func (m *MockClient) Doc(ctx context.Context, path string, _ int64) (*doc.JSONDocumentation, error)
- func (m *MockClient) File(ctx context.Context, pkgPath, fileName string, _ int64) ([]byte, FileMeta, error)
- func (m *MockClient) ListFiles(ctx context.Context, path string, _ int64) ([]string, error)
- func (m *MockClient) ListPaths(ctx context.Context, prefix string, limit int) ([]string, error)
- func (m *MockClient) Realm(ctx context.Context, path, args string) ([]byte, error)
- func (m *MockClient) StateObject(_ context.Context, _ string, _ int64) ([]byte, error)
- func (m *MockClient) StatePkg(_ context.Context, path string, _ int64) ([]byte, error)
- func (m *MockClient) StateType(_ context.Context, _ string, _ int64) ([]byte, error)
- type MockPackage
- type RealmDirectory
- type RealmRenderContext
- type RenderConfig
- type Renderer
- type StaticMetadata
Constants ¶
const MaxUserContributions = 200
MaxUserContributions caps how many contributions /u/<user> renders. Each entry costs a bech32 decode, a weburl parse, and a sort comparison; an unbounded cap turns a single GET into a 10k-iteration amplifier. Exported so external tests assert against the documented cap. TODO: paginate via ?page= when a contributor exceeds this cap.
const ReadmeFileName = "README.md"
Variables ¶
var ( ErrClientPackageNotFound = errors.New("package not found") ErrClientFileNotFound = errors.New("file not found") ErrClientObjectNotFound = errors.New("object not found") ErrClientRenderNotDeclared = errors.New("render function not declared") ErrClientBadRequest = errors.New("bad request") ErrClientTimeout = errors.New("RPC node request timeout") ErrClientResponse = errors.New("RPC node response error") ErrClientResponseTooLarge = errors.New("RPC node response too large") )
var DefaultAliases = map[string]AliasTarget{ "/": {"/r/gnoland/home", GnowebPath}, "/about": {"/r/gnoland/pages:p/about", GnowebPath}, "/gnolang": {"/r/gnoland/pages:p/gnolang", GnowebPath}, "/ecosystem": {"/r/gnoland/pages:p/ecosystem", GnowebPath}, "/start": {"/r/gnoland/pages:p/start", GnowebPath}, "/license": {"/r/gnoland/pages:p/license", GnowebPath}, "/contribute": {"/r/gnoland/pages:p/contribute", GnowebPath}, "/links": {"/r/gnoland/pages:p/links", GnowebPath}, "/events": {"/r/devrels/events", GnowebPath}, "/partners": {"/r/gnoland/pages:p/partners", GnowebPath}, "/docs": {"/u/docs", GnowebPath}, }
var DefaultCacheAssetsHandler = func(next http.Handler) http.Handler { return CacheHandler(assetsHash, next) }
var DefaultChromaDarkRenderStyle = styles.Get("nord")
var DefaultChromaRenderStyle = styles.Get("friendly")
var Redirects = map[string]string{
"/r/demo/boards:gnolang/6": "/r/demo/boards:gnolang/3",
"/blog": "/r/gnoland/blog",
"/gor": "/contribute",
"/game-of-realms": "/contribute",
"/grants": "/partners",
"/language": "/gnolang",
"/getting-started": "/start",
"/newsletter": "/r/gnoland/pages:p/newsletter",
}
Redirects is a map of gnoweb paths that are redirected using RedirectMiddleware.
Functions ¶
func AssetHandler ¶
AssetHandler returns an http.Handler to serve static assets from the embedded filesystem. Assets are always served from the embedded /public directory.
func CacheHandler ¶
CacheHandler adds ETag and Cache-Control headers to all asset responses for caching.
func CreateUsernameFromBech32 ¶
TODO: Check username from r/sys/users in addition to bech32 address test (username + gno address to be used) CreateUsernameFromBech32 creates a shortened version of the username if it's a valid bech32 address.
func GetClientErrorStatusView ¶
GetClientErrorStatusView wraps clientErrorMessage into a renderable View. `height` is the optional ?height=N pin from the URL — pass 0 when the caller does not propagate it to the chain query.
func NewDefaultChromaOptions ¶
func NewDefaultChromaOptions() []chromahtml.Option
NewDefaultChromaOptions returns the default Chroma options for syntax highlighting.
func NewDefaultGoldmarkOptions ¶
NewDefaultGoldmarkOptions returns the default Goldmark options for Markdown rendering.
func NewRouter ¶
NewRouter initializes the gnoweb router with the specified logger and configuration. It sets up all routes, static asset handling, and middleware.
func NoCacheHandler ¶
NoCacheHandler always invalidates cache for all responses.
func RedirectMiddleware ¶
func RedirectMiddleware(next http.Handler, meta StaticMetadata) http.Handler
RedirectMiddleware redirects all incoming requests whose path matches any of the Redirects to the corresponding URL, and renders a redirect view.
Types ¶
type AliasTarget ¶
type AppConfig ¶
type AppConfig struct {
// UnsafeHTML, if enabled, allows to use HTML in the markdown.
UnsafeHTML bool
// Analytics enables SimpleAnalytics.
Analytics bool
// AnalyticsHostname, when non-empty, is rendered as data-hostname on the
// SimpleAnalytics script tag to override the hostname SA reports.
// Set this when the site listens on a host SA would otherwise report
// incorrectly (for example a non-default port in local development).
AnalyticsHostname string
// NodeRemote is the remote address of the gno.land node.
NodeRemote string
// NodeRequestTimeout define how much time a request to the remote node should live before timeout.
NodeRequestTimeout time.Duration
// RemoteHelp is the remote of the gno.land node, as used in the help page.
RemoteHelp string
// AssetsPath is the base path to the gnoweb assets.
AssetsPath string
// NoAssetsCache disables assets caching.
NoAssetsCache bool
// ChainID is the chain id, used for constructing the help page.
ChainID string
// FaucetURL, if specified, will be the URL to which `/faucet` redirects.
FaucetURL string
// Domain is the domain used by the node.
Domain string
// Banner, if set, displays a site-wide banner above the header.
Banner components.BannerData
// Aliases is a map of aliases pointing to another path or a static file.
Aliases map[string]AliasTarget
// RenderConfig defines the default configuration for rendering realms and source files.
RenderConfig RenderConfig
// StateRateLimitPerMinute caps the per-IP request rate against
// ?state* URLs (also used as the token-bucket burst). 0 ⇒ the
// HTTPHandler default (100/min). ADR-003 §Resource bounds.
StateRateLimitPerMinute int
// StateRateLimitTrustedProxies is the list of trusted reverse-proxy
// CIDRs (or bare IPs) for the per-IP rate limiter. X-Real-IP is honored
// only for connections originating inside one of these networks; empty
// (the default) trusts nothing, so untrusted deployments never trust
// attacker-controlled headers. ADR-003 §Resource bounds.
StateRateLimitTrustedProxies []string
// MaxConcurrentRPC caps in-flight outbound RPCs per gnoweb instance
// against the chain node. 0 ⇒ the rpcClient default (32). Tighten on
// chain nodes under pressure; relax when capacity allows. ADR-003
// §Resource bounds.
MaxConcurrentRPC int
}
AppConfig contains configuration for gnoweb.
func NewDefaultAppConfig ¶
func NewDefaultAppConfig() *AppConfig
NewDefaultAppConfig returns a new default AppConfig. The default sets 127.0.0.1:26657 as the remote node, "dev" as the chain ID, and sets up assets to be served on /public/.
type ClientAdapter ¶
type ClientAdapter interface {
// Realm fetch the content of a realm from a given path and
// return the data.
Realm(ctx context.Context, path, args string) ([]byte, error) // raw Render() bytes
// File fetches the source file from a given package path and
// filename. `height = 0` queries the latest block; positive values
// pin the query to that historical height.
File(ctx context.Context, path, filename string, height int64) ([]byte, FileMeta, error)
// ListFiles lists all source files available in a specified
// package path. `height = 0` queries the latest block; non-zero
// pins the listing to a historical block.
ListFiles(ctx context.Context, path string, height int64) ([]string, error)
// QueryPath list any path given the specified prefix
ListPaths(ctx context.Context, prefix string, limit int) ([]string, error)
// Doc retrieves the JSON doc suitable for printing from a
// specified package path. `height = 0` queries the latest block;
// any positive value pins the query to that historical height.
Doc(ctx context.Context, path string, height int64) (*doc.JSONDocumentation, error)
// StatePkg retrieves the root state tree for a package. `height
// = 0` queries the latest block; positive values are forwarded
// to ABCI as-is.
StatePkg(ctx context.Context, path string, height int64) ([]byte, error)
// StateObject retrieves the children of an object by ObjectID at
// the given block height (0 for latest).
StateObject(ctx context.Context, oid string, height int64) ([]byte, error)
// StateType retrieves a type definition by TypeID at the given
// block height (0 for latest).
StateType(ctx context.Context, typeId string, height int64) ([]byte, error)
}
func NewRPCClientAdapter ¶
func NewRPCClientAdapter(logger *slog.Logger, cli *client.RPCClient, domain string, maxConcurrentRPC int) ClientAdapter
NewRPCClientAdapter creates a new instance of rpcClient. maxConcurrentRPC ≤ 0 ⇒ defaultMaxConcurrentRPC; positive values cap in-flight outbound RPCs at that count.
type HTMLRenderer ¶
type HTMLRenderer struct {
// contains filtered or unexported fields
}
HTMLRenderer implements the Renderer interface for HTML output.
func NewHTMLRenderer ¶
func NewHTMLRenderer(logger *slog.Logger, cfg RenderConfig, client ClientAdapter) *HTMLRenderer
func (*HTMLRenderer) RenderDocumentation ¶
func (r *HTMLRenderer) RenderDocumentation(w io.Writer, src []byte) error
RenderDocumentation writes the HTML representation of doc-context markdown to w. HTML escaping is delegated to Goldmark.
func (*HTMLRenderer) RenderRealm ¶
func (r *HTMLRenderer) RenderRealm(w io.Writer, u *weburl.GnoURL, src []byte, ctx RealmRenderContext) (md.Toc, error)
RenderRealm renders a realm to HTML and returns a table of contents.
func (*HTMLRenderer) RenderSource ¶
RenderSource renders a source file into HTML with syntax highlighting based on its extension.
func (*HTMLRenderer) WriteChromaCSS ¶
func (r *HTMLRenderer) WriteChromaCSS(w io.Writer) error
WriteChromaCSS writes the CSS for syntax highlighting to the provided writer. It outputs the light theme by default and, if configured, the dark theme scoped under [data-theme="dark"] using CSS nesting.
type HTTPHandler ¶
type HTTPHandler struct {
Logger *slog.Logger
Static StaticMetadata
Client ClientAdapter
Renderer Renderer
Aliases map[string]AliasTarget
Timeout time.Duration
// State is the feature/state handler that owns every ?state* URL.
// Built in NewHTTPHandler so the wire-in dispatch hook is a single
// method call (ADR-003 §Architecture).
State *state.Handler
}
HTTPHandler processes HTTP requests for gnoweb.
func NewHTTPHandler ¶
func NewHTTPHandler(logger *slog.Logger, cfg *HTTPHandlerConfig) (*HTTPHandler, error)
NewHTTPHandler creates a new HTTPHandler.
func (*HTTPHandler) Get ¶
func (h *HTTPHandler) Get(w http.ResponseWriter, r *http.Request)
Get processes a GET HTTP request and renders the appropriate page.
func (*HTTPHandler) GetDirectoryView ¶
func (h *HTTPHandler) GetDirectoryView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
GetDirectoryView renders the directory view for a package, showing available files.
func (*HTTPHandler) GetHelpView ¶
func (h *HTTPHandler) GetHelpView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
func (*HTTPHandler) GetMarkdownView ¶
func (h *HTTPHandler) GetMarkdownView(gnourl *weburl.GnoURL, mdContent string) (int, *components.View)
GetMarkdownView handles rendering of markdown files.
func (*HTTPHandler) GetPackageView ¶
func (h *HTTPHandler) GetPackageView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
GetPackageView handles package pages, including help, source, directory, and user views.
func (*HTTPHandler) GetPathsListView ¶
func (h *HTTPHandler) GetPathsListView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
func (*HTTPHandler) GetRealmView ¶
func (h *HTTPHandler) GetRealmView(ctx context.Context, gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)
GetRealmView renders a realm page or returns an error/status if not available.
func (*HTTPHandler) GetSourceView ¶
func (h *HTTPHandler) GetSourceView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
func (*HTTPHandler) GetUserView ¶
func (h *HTTPHandler) GetUserView(ctx context.Context, gnourl *weburl.GnoURL) (int, *components.View)
GetUserView returns the user profile view for a given GnoURL.
func (*HTTPHandler) Post ¶
func (h *HTTPHandler) Post(w http.ResponseWriter, r *http.Request)
Post processes a POST HTTP request.
func (*HTTPHandler) ServeHTTP ¶
func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP handles HTTP requests and only allows GET requests.
func (*HTTPHandler) ServeSourceDownload ¶
func (h *HTTPHandler) ServeSourceDownload(ctx context.Context, gnourl *weburl.GnoURL, w http.ResponseWriter, r *http.Request)
ServeSourceDownload handles downloading a source file as plain text.
type HTTPHandlerConfig ¶
type HTTPHandlerConfig struct {
Meta StaticMetadata
ClientAdapter ClientAdapter
Renderer Renderer
Aliases map[string]AliasTarget
Timeout time.Duration
// StateRateLimitPerMinute caps per-IP requests against ?state* URLs.
// 0 ⇒ defaultStateRateLimitPerMinute. Also used as the token-bucket
// burst. ADR-003 §Resource bounds.
StateRateLimitPerMinute int
// StateRateLimitTrustedProxies — see AppConfig field of the same name.
StateRateLimitTrustedProxies []string
}
HTTPHandlerConfig configures an HTTPHandler.
type MockClient ¶
type MockClient struct {
Packages map[string]*MockPackage // path -> package
}
MockClient is a mock implementation of the ClientAdapter interface for testing.
func NewMockClient ¶
func NewMockClient(pkgs ...*MockPackage) *MockClient
NewMockClient creates a new MockClient from one or more MockPackages.
func (*MockClient) Doc ¶
func (m *MockClient) Doc(ctx context.Context, path string, _ int64) (*doc.JSONDocumentation, error)
Doc retrieves the JSON documentation for a specified package path.
func (*MockClient) File ¶
func (m *MockClient) File(ctx context.Context, pkgPath, fileName string, _ int64) ([]byte, FileMeta, error)
File fetches the source file from a given package path and filename, returning its content and metadata.
func (*MockClient) ListFiles ¶
ListFiles lists all source files available in a specified package path.
func (*MockClient) ListPaths ¶
ListPaths lists all package paths that match the specified prefix, up to the given limit.
func (*MockClient) Realm ¶
Realm fetches the content of a realm from a given path and returns the data, or an error if not found or not declared.
func (*MockClient) StateObject ¶
StateObject returns mock object state data for testing.
type MockPackage ¶
type MockPackage struct {
Path string
Domain string
Files map[string]string // filename -> body
Functions []*doc.JSONFunc
}
MockPackage represents a mock package with files and function signatures for testing.
type RealmDirectory ¶
type RealmDirectory interface {
// Paths returns the realm (/r/) and package (/p/) paths known to the chain.
Paths(ctx context.Context) (realms, packages []string, err error)
}
RealmDirectory exposes realm and package paths for discovery. It is the seam behind which the source can evolve (live RPC today, a dedicated search index later) without touching callers.
type RealmRenderContext ¶
RealmRenderContext holds context information for rendering realms
type RenderConfig ¶
type RenderConfig struct {
ChromaStyle *chroma.Style
ChromaDarkStyle *chroma.Style
ChromaOptions []chromahtml.Option
GoldmarkOptions []goldmark.Option
}
RenderConfig holds configuration for syntax highlighting and Markdown rendering.
func NewDefaultRenderConfig ¶
func NewDefaultRenderConfig() (cfg RenderConfig)
NewDefaultRenderConfig returns a RenderConfig with default styles and options.
type Renderer ¶
type Renderer interface {
RenderRealm(w io.Writer, u *weburl.GnoURL, src []byte, ctx RealmRenderContext) (md.Toc, error)
RenderSource(w io.Writer, name string, src []byte) error
// RenderDocumentation renders doc-context markdown (from vm/qdoc) to HTML.
// Fenced and indented code blocks are wrapped in collapsible <details>
// with Chroma highlighting. HTML escaping is delegated to Goldmark.
RenderDocumentation(w io.Writer, src []byte) error
}
Renderer defines the interface for rendering realms, source files, and doc-context markdown (function/type/package documentation).
type StaticMetadata ¶
type StaticMetadata struct {
Domain string
AssetsPath string
ChromaPath string
RemoteHelp string
ChainId string
Analytics bool
AnalyticsHostname string
BuildTime string
Banner components.BannerData
}
StaticMetadata holds static configuration for a web handler.
func (StaticMetadata) RedirectAnalytics ¶
func (s StaticMetadata) RedirectAnalytics() components.AnalyticsData
RedirectAnalytics builds the AnalyticsData for a redirect view. The redirect view is rendered outside IndexLayout, so the analytics fields must be populated explicitly rather than derived from HeadData.