Help us shape the future of Go! Take the 2026 Go Developer Survey

schema

package
v0.26.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package schema defines the immutable, versioned representation of a resolved Ridu configuration.

Resolved schemas contain declarative metadata only. They never contain executable access rules, secrets, or database connections.

Index

Constants

View Source
const CurrentAdminPluginAPIVersion uint32 = 1

CurrentAdminPluginAPIVersion is the static backend/admin pairing contract understood by this manifest version.

View Source
const CurrentPluginAPIVersion uint32 = 1

CurrentPluginAPIVersion is the compiled backend plugin contract represented by this manifest version.

View Source
const EmbeddedTreeVersion uint32 = 1

EmbeddedTreeVersion is the declarative embedded-value metadata contract.

Variables

This section is empty.

Functions

func BindBlockReferences added in v0.2.0

func BindBlockReferences(snapshot *Snapshot) error

BindBlockReferences validates the block graph and attaches lazy placement views. Every container must select known definitions without repeats; the definitions must be acyclic, keep every placement path within the nesting and query path bounds (see pathExtent), and derive distinct stable IDs (see validatePlacementIDs). Each check visits every definition once, so validation cost follows the number of definitions rather than placements. It does not evaluate access, defaults, hooks or other executable behavior. Failures are a *ValidationError naming the responsible definitions.

func ClearDescendantLocalization added in v0.15.0

func ClearDescendantLocalization(field *Field)

ClearDescendantLocalization marks every descendant of a localized field unlocalized during config resolution, because the field stores one complete child tree per locale. Nested fields change in place; block placements inherit the cleared locale scope without being materialized.

func EachDefinitionChildList added in v0.15.0

func EachDefinitionChildList(field Field, visit func([]Field))

EachDefinitionChildList calls visit with each immediate child field list of field: a group or array's fields and each selectable block definition's fields, as DefinitionChildFields enters them. A shared definition passes the same slice at every placement, so callers can memoize by its first element.

func EqualFields added in v0.15.0

func EqualFields(left, right []Field) bool

EqualFields reports whether two field lists, each bound to its own schema's block definitions, describe the same fields at every placement: equal field metadata and equal selected definitions. Lazy bindings and materialized placement views are not compared, so the result does not depend on how either schema was traversed. Each definition is compared once, so the cost follows definitions rather than placements.

func IsSupportedEndpointMethod

func IsSupportedEndpointMethod(method string) bool

IsSupportedEndpointMethod reports whether method is part of the custom endpoint contract. Config resolution stores supported methods in uppercase.

func IsValidAdminPluginAsset

func IsValidAdminPluginAsset(value string) bool

IsValidAdminPluginAsset reports whether value is a safe package-relative side-effect import generated into the static admin entry.

func IsValidAdminPluginExport

func IsValidAdminPluginExport(value string) bool

IsValidAdminPluginExport reports whether value can be used as a named JavaScript import without computed or executable syntax.

func IsValidAdminPluginPackage

func IsValidAdminPluginPackage(value string) bool

IsValidAdminPluginPackage reports whether value is a static JavaScript package specifier rather than a relative path or generated-code fragment.

func IsValidAdminPluginRoute

func IsValidAdminPluginRoute(value string) bool

IsValidAdminPluginRoute reports whether a literal relative plugin route stays outside framework-owned namespaces, matching admin registration rules.

func IsValidBlockTypeName added in v0.2.0

func IsValidBlockTypeName(value string) bool

IsValidBlockTypeName reports whether a generated block name is portable to Go and TypeScript.

func IsValidCollectionSlug

func IsValidCollectionSlug(value string) bool

IsValidCollectionSlug reports whether a collection slug has the canonical lowercase kebab-case form.

func IsValidEndpointPath

func IsValidEndpointPath(path string) bool

IsValidEndpointPath reports whether path is a deterministic custom endpoint pattern. Paths begin with / and may use complete named segments such as :id. Query strings, fragments, traversal, empty segments, and partial parameters are rejected.

func IsValidFieldName

func IsValidFieldName(value string) bool

IsValidFieldName reports whether a field name is safe as an unquoted generated property and query path segment.

func IsValidGoPackage

func IsValidGoPackage(value string) bool

IsValidGoPackage reports whether value is a portable Go import path.

func IsValidLocaleCode

func IsValidLocaleCode(value string) bool

IsValidLocaleCode reports whether a locale code is safe in URLs, generated contracts, and deterministic PostgreSQL identifiers. Request control tokens are reserved and cannot be configured as locales.

func IsValidPluginKey

func IsValidPluginKey(value string) bool

IsValidPluginKey reports whether a plugin key has the canonical kebab-case form.

func IsValidSemanticVersion

func IsValidSemanticVersion(value string) bool

IsValidSemanticVersion reports whether value is a complete semantic version.

func IsValidSemanticVersionRange

func IsValidSemanticVersionRange(minimum, maximumExclusive string) bool

IsValidSemanticVersionRange reports whether minimum and the optional exclusive maximum form a non-empty semantic-version interval.

func IsValidStableID

func IsValidStableID(value string) bool

IsValidStableID reports whether a stable ID has the canonical kebab-case form.

func IsValidTimeZoneID added in v0.3.0

func IsValidTimeZoneID(value string) bool

IsValidTimeZoneID reports whether value is UTC, a ±HH:mm offset, or a safe slash-delimited IANA timezone such as Europe/London.

func SemanticVersionInRange

func SemanticVersionInRange(version, minimum, maximumExclusive string) bool

SemanticVersionInRange reports whether version is inside a validated inclusive-minimum, exclusive-maximum interval.

func ValidateAdminLoaders added in v0.3.0

func ValidateAdminLoaders(loaders []AdminLoader) error

ValidateAdminLoaders checks serialized contracts at manifest and generator boundaries.

func ValidateEmbeddedMetadata added in v0.2.0

func ValidateEmbeddedMetadata(snapshot Snapshot) error

ValidateEmbeddedMetadata validates descriptor structure before consumers can interpret it. Finite schema depth also rejects recursive/cyclic schema graphs. A block definition's fields are the same at every placement, so each block is checked at its first placement only; issue paths name that placement.

func ValidateEmbeddedTrees added in v0.2.0

func ValidateEmbeddedTrees(trees []EmbeddedTree, path string) error

ValidateEmbeddedTrees checks the bounded descriptor language. Roots must be disjoint so the same structural node cannot be consumed by two descriptors.

func ValidateFieldEditor added in v0.2.0

func ValidateFieldEditor(kind FieldType, editor *FieldEditor) error

ValidateFieldEditor validates presentation metadata independently of frontend code.

func ValidateFieldEditors added in v0.2.0

func ValidateFieldEditors(snapshot Snapshot) error

ValidateFieldEditors checks local editor declarations before generation or runtime use.

func WalkDefinitionFields added in v0.15.0

func WalkDefinitionFields(visit func(Field) bool, roots ...[]Field) bool

WalkDefinitionFields calls visit for each field reachable from the roots through DefinitionChildFields, in pre-order. Each shared definition's fields are visited once, however often the definition is placed, so the walk is proportional to definitions. It stops and returns false when visit does.

func WalkPlacements added in v0.15.0

func WalkPlacements(fields []Field, visit func(segments []string, field Field, shared bool) bool)

WalkPlacements calls visit for every field placement beneath a resource's fields, with the placement's absolute path segments, without creating placement views. shared reports a field of a block definition, whose own Path and ID are definition-relative; PlacementFieldID derives its placement ID from the segments. visit reports whether to visit the field's descendants. A complete walk is proportional to placements, so use it only for work that is inherently per placement, and prune it; segments is reused between calls.

Types

type AdminDataType added in v0.3.0

type AdminDataType struct {
	Kind     string                   `json:"kind"`
	Nullable bool                     `json:"nullable,omitempty"`
	Optional bool                     `json:"optional,omitempty"`
	Fields   map[string]AdminDataType `json:"fields,omitempty"`
	Element  *AdminDataType           `json:"element,omitempty"`
}

AdminDataType is the JSON subset supported by typed admin loaders. Inputs are objects of scalar query parameters; outputs may contain nested objects and arrays. Optional marks an omitted object property, Nullable a JSON null.

type AdminLanguage

type AdminLanguage struct {
	Code              string            `json:"code"`
	Label             string            `json:"label"`
	LabelTranslations map[string]string `json:"labelTranslations,omitempty"`
	RTL               bool              `json:"rtl,omitempty"`
}

AdminLanguage is one statically bundled interface language.

type AdminLoader added in v0.3.0

type AdminLoader struct {
	Key    string        `json:"key"`
	Input  AdminDataType `json:"input"`
	Output AdminDataType `json:"output"`
}

AdminLoader describes a compiled, authenticated admin read. Executable code remains in core; these JSON shapes drive generated browser contracts.

type AdminLocalizationSettings

type AdminLocalizationSettings struct {
	Languages       []AdminLanguage `json:"languages"`
	DefaultLanguage string          `json:"defaultLanguage"`
	TimeZones       []AdminTimeZone `json:"timeZones,omitempty"`
	DefaultTimeZone string          `json:"defaultTimeZone,omitempty"`
}

AdminLocalizationSettings configures translated interface presentation. It remains independent from content LocalizationSettings.

type AdminSettings

type AdminSettings struct {
	// UserCollectionID is the durable identity of the selected auth collection.
	UserCollectionID StableID `json:"userCollectionId"`
	// UserCollectionSlug is the API-facing slug of the selected auth collection.
	UserCollectionSlug CollectionSlug `json:"userCollectionSlug"`
}

AdminSettings identifies the auth collection trusted by the admin UI.

type AdminTimeZone

type AdminTimeZone struct {
	ID                string            `json:"id"`
	Label             string            `json:"label"`
	LabelTranslations map[string]string `json:"labelTranslations,omitempty"`
}

AdminTimeZone is one IANA timezone offered to editors.

type Application

type Application struct {
	AdminLoaders []AdminLoader `json:"adminLoaders,omitempty"`
	// Name is the resolved author-facing application name.
	Name string `json:"name"`
	// NameTranslations overrides Name for configured admin interface languages.
	NameTranslations map[string]string `json:"nameTranslations,omitempty"`
	// AllowIDOnCreate permits callers to supply a validated canonical string ID
	// on ordinary creates. Migration imports preserve source IDs independently.
	AllowIDOnCreate bool `json:"allowIDOnCreate,omitempty"`
	// Admin contains admin authentication policy when auth is enabled.
	Admin *AdminSettings `json:"admin,omitempty"`
	// AdminLocalization is the deterministic interface language and timezone
	// contract. Catalog text is supplied by the statically built admin.
	AdminLocalization *AdminLocalizationSettings `json:"adminLocalization,omitempty"`
	// Localization is the deterministic content-locale contract, when enabled.
	Localization *LocalizationSettings `json:"localization,omitempty"`
	// Endpoints lists application-level custom endpoint metadata. Executable
	// handlers remain in Go runtime configuration.
	Endpoints []Endpoint `json:"endpoints,omitempty"`
}

Application contains framework-level application metadata.

type ArrayRowLabels

type ArrayRowLabels struct {
	Singular             string            `json:"singular"`
	SingularTranslations map[string]string `json:"singularTranslations,omitempty"`
	Plural               string            `json:"plural"`
	PluralTranslations   map[string]string `json:"pluralTranslations,omitempty"`
}

ArrayRowLabels contains singular and plural author-facing array item names.

type AuthSettings

type AuthSettings struct {
	IdentityField                     string `json:"identityField"`
	SessionDurationSeconds            int64  `json:"sessionDurationSeconds"`
	PasswordMinLength                 int    `json:"passwordMinLength"`
	PasswordMaxBytes                  int    `json:"passwordMaxBytes"`
	PasswordBcryptCost                int    `json:"passwordBcryptCost"`
	MaxLoginAttempts                  int    `json:"maxLoginAttempts"`
	LockDurationSeconds               int64  `json:"lockDurationSeconds"`
	PasswordReset                     bool   `json:"passwordReset"`
	PasswordResetTokenDurationSeconds int64  `json:"passwordResetTokenDurationSeconds"`
	VerifyEmail                       bool   `json:"verifyEmail"`
	VerificationTokenDurationSeconds  int64  `json:"verificationTokenDurationSeconds"`
	APIKeys                           bool   `json:"apiKeys"`
}

type BlockAdmin added in v0.2.0

type BlockAdmin struct {
	RowLabel string `json:"rowLabel,omitempty"`
	// contains filtered or unexported fields
}

BlockAdmin contains presentation metadata derived from direct block children.

func (BlockAdmin) MarshalJSON added in v0.14.0

func (admin BlockAdmin) MarshalJSON() ([]byte, error)

MarshalJSON encodes block presentation metadata, retaining recorded history.

func (*BlockAdmin) UnmarshalJSON added in v0.14.0

func (admin *BlockAdmin) UnmarshalJSON(encoded []byte) error

UnmarshalJSON decodes block presentation metadata. Parse applies the current authoring rules; ParseHistorical validates recorded naming metadata instead.

type BlockDefinitions added in v0.15.0

type BlockDefinitions struct {
	// contains filtered or unexported fields
}

BlockDefinitions holds the block definitions of one schema and the definition views shared by all of their placements. A builder may add definitions while it resolves configuration; views are created on first use.

func NewBlockDefinitions added in v0.15.0

func NewBlockDefinitions(templates map[string]BlockType) *BlockDefinitions

NewBlockDefinitions shares templates, a map of definition-relative blocks by slug. The caller must not change a template once a placement or definition view may have read it.

type BlockLabels added in v0.2.0

type BlockLabels struct {
	Singular             string            `json:"singular"`
	Plural               string            `json:"plural"`
	SingularTranslations map[string]string `json:"singularTranslations,omitempty"`
	PluralTranslations   map[string]string `json:"pluralTranslations,omitempty"`
}

BlockLabels contains resolved author-facing names and admin language overrides.

type BlockType

type BlockType struct {
	TypeName string      `json:"typeName,omitempty"`
	Admin    *BlockAdmin `json:"admin,omitempty"`
	Slug     string      `json:"slug"`
	Labels   BlockLabels `json:"labels"`
	Fields   []Field     `json:"fields"`
	// contains filtered or unexported fields
}

func BlockTemplate added in v0.2.0

func BlockTemplate(block BlockType, resource StableID, prefix []string) BlockType

BlockTemplate detaches one resolved definition and makes field paths relative to its root. Nested containers stay compact selections of other definitions.

func (BlockType) ResolvedFields added in v0.2.0

func (b BlockType) ResolvedFields() []Field

ResolvedFields exposes placement-aware children. Definition metadata is shared; child placement views are materialized only when traversed. As with other snapshot fields, callers must not mutate a view concurrently with traversal.

type BlocksField

type BlocksField struct {
	BlockReferences []string `json:"blockReferences,omitempty"`

	MinRows int `json:"minRows,omitempty"`
	MaxRows int `json:"maxRows,omitempty"`
	// contains filtered or unexported fields
}

BlocksField selects the block definitions a row may use, by slug, from the manifest's Blocks registry. Inline declarations resolve to registered definitions, so every container has this one representation.

func ReferenceTypes added in v0.2.0

func ReferenceTypes(slugs []string, definitions *BlockDefinitions, resource StableID, path []string) *BlocksField

ReferenceTypes binds a container during config resolution. The definitions are builder-owned until the final immutable manifest is installed.

func (BlocksField) Definition added in v0.15.0

func (b BlocksField) Definition(slug string) (BlockType, bool)

Definition returns the block type that slug selects, as Definitions does.

func (BlocksField) Definitions added in v0.15.0

func (b BlocksField) Definitions() []BlockType

Definitions returns the block types a row may select without creating placement views: each is its shared definition view, the same values at every placement, with definition-relative paths and IDs and this placement's inherited locale scope, whose nested containers also yield definition views. Work keyed by these values is therefore proportional to block definitions. The result is shared and read-only.

func (BlocksField) ResolvedTypes added in v0.2.0

func (b BlocksField) ResolvedTypes() []BlockType

ResolvedTypes returns placement views: each selected block's fields carry this placement's resource path and stable IDs. A materialized view is kept for the life of the schema, so traversing every placement costs time and memory for every path through the block graph. Processing that needs only field structure uses Definitions instead.

type Capabilities

type Capabilities struct {
	Auth     bool `json:"auth"`
	Upload   bool `json:"upload"`
	Versions bool `json:"versions"`
	Trash    bool `json:"trash"`
	Locking  bool `json:"locking,omitempty"`
	Global   bool `json:"global,omitempty"`
}

Capabilities reserves explicit, typed manifest positions for collection behaviors that arrive in later vertical slices.

type CodeField

type CodeField struct {
	Language  string `json:"language,omitempty"`
	MinLength *int   `json:"minLength,omitempty"`
	MaxLength *int   `json:"maxLength,omitempty"`
}

CodeField contains editor metadata for a stored source string.

type Collection

type Collection struct {
	ID           StableID              `json:"id"`
	Slug         CollectionSlug        `json:"slug"`
	Labels       CollectionLabels      `json:"labels"`
	Admin        CollectionAdmin       `json:"admin"`
	Capabilities Capabilities          `json:"capabilities"`
	Auth         *AuthSettings         `json:"authSettings,omitempty"`
	Upload       *UploadSettings       `json:"uploadSettings,omitempty"`
	Versions     *VersionSettings      `json:"versionSettings,omitempty"`
	DocumentLock *DocumentLockSettings `json:"documentLockSettings,omitempty"`
	Fields       []Field               `json:"fields"`
	Indexes      []CollectionIndex     `json:"indexes,omitempty"`
	Endpoints    []Endpoint            `json:"endpoints,omitempty"`
}

Collection is one resolved collection schema.

type CollectionAdmin

type CollectionAdmin struct {
	// Hidden keeps the resource out of the admin's navigation, dashboard,
	// search and routes. It is presentation only.
	Hidden                  bool              `json:"hidden,omitempty"`
	UseAsTitle              string            `json:"useAsTitle,omitempty"`
	DefaultColumns          []string          `json:"defaultColumns,omitempty"`
	Group                   string            `json:"group,omitempty"`
	GroupTranslations       map[string]string `json:"groupTranslations,omitempty"`
	Description             string            `json:"description,omitempty"`
	DescriptionTranslations map[string]string `json:"descriptionTranslations,omitempty"`
	FolderField             string            `json:"folderField,omitempty"`
	ParentField             string            `json:"parentField,omitempty"`
	LivePreview             *LivePreview      `json:"livePreview,omitempty"`
}

type CollectionIndex

type CollectionIndex struct {
	Fields []query.Path `json:"fields"`
	Unique bool         `json:"unique,omitempty"`
}

CollectionIndex is one ordered compound index over supported field paths. Unique indexes use NULLS DISTINCT semantics in every official store.

type CollectionLabels

type CollectionLabels struct {
	Singular             string            `json:"singular"`
	SingularTranslations map[string]string `json:"singularTranslations,omitempty"`
	Plural               string            `json:"plural"`
	PluralTranslations   map[string]string `json:"pluralTranslations,omitempty"`
}

CollectionLabels contains normalized author-facing names.

type CollectionSlug

type CollectionSlug string

CollectionSlug is the URL- and API-facing name of a collection.

type DateField

type DateField struct {
	Format DateFormat `json:"format"`
}

DateField describes how a stored date string is authored and presented.

type DateFormat added in v0.2.0

type DateFormat string

DateFormat identifies the accepted date string contract across APIs and admin.

const (
	DateOnly DateFormat = "date"
	DateTime DateFormat = "date-time"
	TimeOnly DateFormat = "time"
)

type DocumentLockSettings

type DocumentLockSettings struct {
	DurationSeconds int64 `json:"durationSeconds"`
}

DocumentLockSettings controls the admin lock lease for one collection.

type EmbeddedTree added in v0.2.0

type EmbeddedTree struct {
	Version  uint32             `json:"version"`
	Key      string             `json:"key"`
	Root     []string           `json:"root"`
	Children string             `json:"children"`
	Tag      string             `json:"tag"`
	Cases    []EmbeddedTreeCase `json:"cases"`
}

EmbeddedTree locates a structural node or node list through literal properties. Only Children is recursively traversed; case payloads use ordinary schemas.

type EmbeddedTreeCase added in v0.2.0

type EmbeddedTreeCase struct {
	BlockReferences []string `json:"blockReferences,omitempty"`

	TagValue      string `json:"tagValue"`
	Payload       string `json:"payload"`
	Discriminator string `json:"discriminator"`
	Identity      string `json:"identity"`
	// contains filtered or unexported fields
}

EmbeddedTreeCase declares schema-owned payloads for one structural node tag. Like a Blocks field, it selects block definitions by slug; an empty selection reserves the envelope while admitting no payloads.

func ReferenceCase added in v0.2.0

func ReferenceCase(c EmbeddedTreeCase, definitions *BlockDefinitions, resource StableID, path []string) EmbeddedTreeCase

ReferenceCase binds an embedded tree case during config resolution, as ReferenceTypes does.

func (EmbeddedTreeCase) Definition added in v0.15.0

func (c EmbeddedTreeCase) Definition(slug string) (BlockType, bool)

Definition returns the case's block type that slug selects.

func (EmbeddedTreeCase) Definitions added in v0.15.0

func (c EmbeddedTreeCase) Definitions() []BlockType

Definitions returns the case's selectable block types, as BlocksField.Definitions does.

func (EmbeddedTreeCase) ResolvedTypes added in v0.2.0

func (c EmbeddedTreeCase) ResolvedTypes() []BlockType

type Endpoint

type Endpoint struct {
	Method  string `json:"method"`
	Path    string `json:"path"`
	Summary string `json:"summary,omitempty"`
}

Endpoint is the deterministic public metadata for one application-authored custom endpoint. Handler code and body limits are runtime-only.

type Field

type Field struct {
	ID        StableID      `json:"id"`
	Name      string        `json:"name"`
	Path      query.Path    `json:"path"`
	Type      FieldType     `json:"type"`
	Category  FieldCategory `json:"category"`
	Required  bool          `json:"required"`
	Unique    bool          `json:"unique"`
	Index     bool          `json:"index,omitempty"`
	Localized bool          `json:"localized,omitempty"`
	// QueryRestricted records an attached read policy's static prohibition on
	// caller filtering, sorting and distinct queries. It is not an access verdict.
	QueryRestricted bool    `json:"queryRestricted,omitempty"`
	Default         *string `json:"default,omitempty"`
	// DynamicDefault permits omitted input to reach server initialization. It does
	// not contain executable code or promise that the callback supplies a value.
	DynamicDefault bool `json:"dynamicDefault,omitempty"`
	// LiveValidation enables explicit advisory server feedback without serializing callbacks.
	LiveValidation bool                `json:"liveValidation,omitempty"`
	Admin          FieldAdmin          `json:"admin"`
	Text           *TextField          `json:"text,omitempty"`
	Textarea       *TextField          `json:"textarea,omitempty"`
	Code           *CodeField          `json:"code,omitempty"`
	Number         *NumberField        `json:"number,omitempty"`
	Date           *DateField          `json:"date,omitempty"`
	Select         *SelectField        `json:"select,omitempty"`
	Point          *PointField         `json:"point,omitempty"`
	UI             *UIField            `json:"ui,omitempty"`
	Join           *JoinField          `json:"join,omitempty"`
	Virtual        *VirtualField       `json:"virtual,omitempty"`
	Relationship   *RelationshipField  `json:"relationship,omitempty"`
	List           *PrimitiveListField `json:"list,omitempty"`
	Upload         *UploadField        `json:"upload,omitempty"`
	Nested         *NestedField        `json:"nested,omitempty"`
	Blocks         *BlocksField        `json:"blocks,omitempty"`
	Plugin         *PluginField        `json:"plugin,omitempty"`
}

Field is one resolved field with exactly one matching typed detail contract.

func ChildFields added in v0.2.0

func ChildFields(field Field) []Field

ChildFields enumerates immediate ordinary schema children, including those declared by plugins. It never examines document values or plugin settings. Like ResolvedFields, the result is a read-only view: when one declaration supplies every child it shares that declaration's slice instead of copying.

func DefinitionChildFields added in v0.15.0

func DefinitionChildFields(field Field) []Field

DefinitionChildFields is ChildFields for processing that needs only field structure: it enters blocks through their shared definitions (see BlocksField.Definitions), so it never creates placement views and its results are the same values wherever a definition is placed. Paths and IDs beneath a block are definition-relative.

func EmbeddedBlocks added in v0.2.0

func EmbeddedBlocks(field Field) []Field

EmbeddedBlocks supplies virtual schema-only Blocks containers for each descriptor case. These do not represent stored fields or queryable columns. They allow schema consumers to reuse the ordinary variant catalog. Each container shares its case's selection: ResolvedTypes returns the case's placement views and Definitions its shared definition views.

func EmbeddedDefinitionBlocks added in v0.15.0

func EmbeddedDefinitionBlocks(field Field) []Field

EmbeddedDefinitionBlocks is EmbeddedBlocks for definition traversal. Definitions and ResolvedTypes of the virtual containers are the case's.

func EmbeddedTypeFields added in v0.2.0

func EmbeddedTypeFields(field Field, selectors []string) []Field

EmbeddedTypeFields selects schema-only payload containers in generic argument order.

func FieldAtPath added in v0.15.0

func FieldAtPath(fields []Field, segments []string) (Field, bool)

FieldAtPath returns the placement view of the field at canonical path segments beneath a resource's fields: field names, with a block slug after a Blocks field and tree key, case tag and slug after an embedding plugin field. It creates placement views only along that path.

type FieldAdmin

type FieldAdmin struct {
	// Extensions are public finite JSON attachments owned by this field.
	Extensions              map[string]json.RawMessage `json:"extensions,omitempty"`
	Editor                  *FieldEditor               `json:"editor,omitempty"`
	Label                   string                     `json:"label"`
	LabelTranslations       map[string]string          `json:"labelTranslations,omitempty"`
	Description             string                     `json:"description,omitempty"`
	DescriptionTranslations map[string]string          `json:"descriptionTranslations,omitempty"`
	Placeholder             string                     `json:"placeholder,omitempty"`
	PlaceholderTranslations map[string]string          `json:"placeholderTranslations,omitempty"`
	ReadOnly                bool                       `json:"readOnly,omitempty"`
	Hidden                  bool                       `json:"hidden,omitempty"`
	Sidebar                 bool                       `json:"sidebar,omitempty"`
	Columns                 int                        `json:"columns,omitempty"`
	Row                     *FieldRow                  `json:"row,omitempty"`
	Collapsible             *FieldCollapsible          `json:"collapsible,omitempty"`
	Tab                     string                     `json:"tab,omitempty"`
	TabTranslations         map[string]string          `json:"tabTranslations,omitempty"`
	TabGroup                *FieldTabGroup             `json:"tabGroup,omitempty"`
	NamedTab                bool                       `json:"namedTab,omitempty"`
	Condition               *FieldCondition            `json:"condition,omitempty"`
	Component               *FieldAdminComponent       `json:"component,omitempty"`
}

FieldAdmin contains serializable presentation metadata, never authorization.

type FieldAdminComponent

type FieldAdminComponent struct {
	// Reference selects an application-local row label; it is not valid for field renderers.
	Reference string          `json:"reference,omitempty"`
	Plugin    string          `json:"plugin,omitempty"`
	Component string          `json:"component,omitempty"`
	Config    json.RawMessage `json:"config,omitempty"`
}

FieldAdminComponent selects one statically registered plugin renderer for a field without changing its storage, validation, access, or generated type.

type FieldCategory

type FieldCategory string

FieldCategory distinguishes broad field behavior without a stringly typed capability map.

const (
	FieldCategoryScalar       FieldCategory = "scalar"
	FieldCategoryNested       FieldCategory = "nested"
	FieldCategoryPresentation FieldCategory = "presentation"
	FieldCategoryRelationship FieldCategory = "relationship"
	FieldCategoryUpload       FieldCategory = "upload"
	FieldCategoryPlugin       FieldCategory = "plugin"
)

type FieldCollapsible

type FieldCollapsible struct {
	ID                 StableID                   `json:"id"`
	Label              string                     `json:"label"`
	LabelTranslations  map[string]string          `json:"labelTranslations,omitempty"`
	InitiallyCollapsed bool                       `json:"initiallyCollapsed,omitempty"`
	Extensions         map[string]json.RawMessage `json:"extensions,omitempty"`
}

FieldCollapsible identifies flattened fields presented inside one disclosure.

type FieldCondition

type FieldCondition struct {
	Kind       FieldConditionKind       `json:"kind"`
	Conditions []FieldCondition         `json:"conditions,omitempty"`
	Predicate  *FieldConditionPredicate `json:"predicate,omitempty"`
}

FieldCondition is one recursive, presentation-only condition node.

type FieldConditionKind

type FieldConditionKind string

FieldConditionKind identifies one node in a deterministic presentation expression.

const (
	FieldConditionKindAll       FieldConditionKind = "all"
	FieldConditionKindAny       FieldConditionKind = "any"
	FieldConditionKindNot       FieldConditionKind = "not"
	FieldConditionKindPredicate FieldConditionKind = "predicate"
)

type FieldConditionOperator

type FieldConditionOperator string

FieldConditionOperator identifies one scalar condition comparison.

const (
	FieldConditionEquals    FieldConditionOperator = "equals"
	FieldConditionNotEquals FieldConditionOperator = "notEquals"
	FieldConditionOneOf     FieldConditionOperator = "oneOf"
)

type FieldConditionPredicate

type FieldConditionPredicate struct {
	Scope    FieldConditionScope    `json:"scope"`
	Path     query.Path             `json:"path"`
	Operator FieldConditionOperator `json:"operator"`
	Values   []ScalarLiteral        `json:"values"`
}

FieldConditionPredicate compares one scoped document value with typed scalars.

type FieldConditionScope

type FieldConditionScope string

FieldConditionScope selects the value tree used by a condition predicate.

const (
	FieldConditionDocument FieldConditionScope = "document"
	FieldConditionSibling  FieldConditionScope = "sibling"
)

type FieldEditor added in v0.2.0

type FieldEditor struct {
	Reference string          `json:"reference"`
	Config    json.RawMessage `json:"config,omitempty"`
}

FieldEditor selects an application-local value editor. Config is public JSON.

type FieldListSet added in v0.15.0

type FieldListSet map[*Field]struct{}

FieldListSet records field lists a definition traversal has entered. A shared definition passes the same slice wherever it is placed, so a traversal that enters each list once does work proportional to definitions.

func (FieldListSet) Add added in v0.15.0

func (set FieldListSet) Add(fields []Field) bool

Add reports whether fields were not yet in the set, adding them. An empty list is never recorded and always reports true.

type FieldRow

type FieldRow struct {
	ID         StableID                   `json:"id"`
	Extensions map[string]json.RawMessage `json:"extensions,omitempty"`
}

FieldRow identifies fields authored as one presentation-only layout row. It never contributes a document path or stored value.

type FieldTabGroup

type FieldTabGroup struct {
	ID         StableID                   `json:"id"`
	Extensions map[string]json.RawMessage `json:"extensions,omitempty"`
}

FieldTabGroup identifies fields authored by one presentation tabs definition. It preserves local tab-group boundaries without contributing a document path.

type FieldTraits added in v0.15.0

type FieldTraits uint8

FieldTraits summarizes the fields of a list or beneath a field, so a value traversal can skip a subtree whose schema cannot need it.

const (
	// FieldTraitLocalized marks a localized field.
	FieldTraitLocalized FieldTraits = 1 << iota
	// FieldTraitEmbedded marks a plugin field that declares embedded schemas.
	FieldTraitEmbedded
)

func DescendantTraits added in v0.15.0

func DescendantTraits(field Field) FieldTraits

DescendantTraits summarizes the fields beneath field, as ListTraits does.

func ListTraits added in v0.15.0

func ListTraits(fields []Field) FieldTraits

ListTraits summarizes fields and all of their descendants. Each block definition is summarized once, however often it is placed.

type FieldType

type FieldType string

FieldType identifies the concrete manifest contract for a field.

const (
	FieldTypeText         FieldType = "text"
	FieldTypeTextList     FieldType = "text-list"
	FieldTypeNumberList   FieldType = "number-list"
	FieldTypeCode         FieldType = "code"
	FieldTypeSelect       FieldType = "select"
	FieldTypeRadio        FieldType = "radio"
	FieldTypePoint        FieldType = "point"
	FieldTypeUI           FieldType = "ui"
	FieldTypeJoin         FieldType = "join"
	FieldTypeVirtual      FieldType = "virtual"
	FieldTypeRelationship FieldType = "relationship"
	FieldTypeUpload       FieldType = "upload"
	FieldTypeGroup        FieldType = "group"
	FieldTypeTextarea     FieldType = "textarea"
	FieldTypeEmail        FieldType = "email"
	FieldTypeDate         FieldType = "date"
	FieldTypeNumber       FieldType = "number"
	FieldTypeCheckbox     FieldType = "checkbox"
	FieldTypeJSON         FieldType = "json"
	FieldTypeArray        FieldType = "array"
	FieldTypeBlocks       FieldType = "blocks"
	FieldTypePlugin       FieldType = "plugin"
)

type Global

type Global = Collection

Global is one resolved singleton schema. It deliberately shares the field, version, and presentation contracts used by collections while living in a separate manifest namespace and API route.

type ImageSize

type ImageSize struct {
	Name   string `json:"name"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	Fit    string `json:"fit"`
}

type Issue

type Issue struct {
	Code    string `json:"code"`
	Path    string `json:"path"`
	Message string `json:"message"`
	// Target correlates a save issue by portable schema and stable row identity.
	// It is opaque to transports and scoped to the operation's locale/form snapshot.
	Target string `json:"target,omitempty"`
	// FieldID and resource identity describe a resolved application-validator target.
	FieldID      StableID `json:"fieldId,omitempty"`
	CollectionID StableID `json:"collectionId,omitempty"`
	GlobalID     StableID `json:"globalId,omitempty"`
	// Locale is the exact translation addressed by a save issue, without fallback.
	Locale LocaleCode `json:"locale,omitempty"`
}

Issue describes one configuration or document validation failure at a field path.

func CascadeReferenceIssues added in v0.9.0

func CascadeReferenceIssues(snapshot Snapshot) []Issue

CascadeReferenceIssues reports each cascade delete policy placed where it would delete a whole owner for one of several references: a has-many, localized or repeated field, or any field of a global, which cannot be deleted.

type JoinField

type JoinField struct {
	CollectionID   StableID       `json:"collectionId"`
	CollectionSlug CollectionSlug `json:"collectionSlug"`
	On             query.Path     `json:"on"`
	Limit          int            `json:"limit"`
	DefaultColumns []string       `json:"defaultColumns,omitempty"`
	DefaultSort    string         `json:"defaultSort,omitempty"`
	AllowCreate    *bool          `json:"allowCreate,omitempty"`
}

JoinField describes a read-only inverse relationship.

type LivePreview

type LivePreview struct {
	URL         string              `json:"url"`
	Breakpoints []PreviewBreakpoint `json:"breakpoints,omitempty"`
}

LivePreview is the serializable document-preview contract consumed by the admin.

type Locale

type Locale struct {
	Code            LocaleCode   `json:"code"`
	Label           string       `json:"label"`
	RTL             bool         `json:"rtl,omitempty"`
	FallbackLocales []LocaleCode `json:"fallbackLocale,omitempty"`
}

Locale is one configured content locale in deterministic authoring order.

type LocaleCode

type LocaleCode string

LocaleCode is the stable request and storage identity of one content locale. It commonly contains a BCP 47 language tag, but may also use an application- owned alphanumeric identifier separated by hyphens or underscores.

type LocalizationSettings

type LocalizationSettings struct {
	Locales       []Locale   `json:"locales"`
	DefaultLocale LocaleCode `json:"defaultLocale"`
	Fallback      bool       `json:"fallback"`
}

LocalizationSettings is the public, serializable content localization contract. Executable locale availability rules remain in Go configuration.

func (LocalizationSettings) LocaleCodes

func (settings LocalizationSettings) LocaleCodes() []LocaleCode

LocaleCodes returns configured locale identities in deterministic authoring order.

type Manifest

type Manifest struct {
	// contains filtered or unexported fields
}

Manifest owns a deeply copied snapshot. Its state cannot be changed through any public accessor.

func NewManifest

func NewManifest(snapshot Snapshot) Manifest

NewManifest freezes an already validated manifest snapshot.

func Parse

func Parse(encoded []byte) (Manifest, error)

Parse decodes a manifest, rejects unknown properties, and verifies that its format version and authoring metadata are supported by this schema package.

func ParseHistorical added in v0.14.0

func ParseHistorical(encoded []byte) (Manifest, error)

ParseHistorical decodes a recorded manifest without imposing the automatic blockName child introduced after earlier version-1 snapshots were stored. It retains those schemas exactly, including an authored blockName of another kind, so digest verification and schema-change admission use the actual prior state. All other format and metadata checks are the same as Parse. Retired admin.nameField metadata is retained privately for historical identity, not exposed as an authoring API or interpreted by the current admin. Use Parse for current generated contracts and executable configuration.

func (Manifest) Bytes

func (manifest Manifest) Bytes() ([]byte, error)

Bytes returns the canonical indented manifest encoding with one trailing newline, suitable for generated artifacts and golden fixtures.

func (Manifest) Equal

func (manifest Manifest) Equal(other Manifest) bool

Equal reports whether two manifests have byte-identical canonical encodings.

func (Manifest) MarshalJSON

func (manifest Manifest) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler without exposing mutable internals.

func (Manifest) SameInstance added in v0.15.0

func (manifest Manifest) SameInstance(other Manifest) bool

SameInstance reports whether manifest and other are copies of one constructed manifest. Manifests are immutable, so data derived from one instance stays valid for all of its copies. Separately constructed equal manifests are different instances.

func (Manifest) SameStorage added in v0.11.0

func (manifest Manifest) SameStorage(other Manifest) bool

SameStorage reports whether two manifests have the same storage schema.

func (Manifest) Snapshot

func (manifest Manifest) Snapshot() Snapshot

Snapshot returns a deep copy of the manifest.

func (Manifest) StorageSchema added in v0.12.0

func (manifest Manifest) StorageSchema() Manifest

StorageSchema returns the manifest without the settings that never shape stored data. Two manifests with the same storage schema describe the same database, so migration history is compared through this projection and presentation changes need no migration. The projection clears:

  • the application name, admin interface languages and timezones, admin loaders, and custom endpoint metadata;
  • labels and admin settings of collections, globals, block types and fields, generated block type names, content-locale labels and direction, select option labels and order, and other editor-only field settings;
  • plugin build metadata: admin packages, endpoints and the generated Go and TypeScript types of plugin fields.

Everything an adapter or validation reads stays, including field types, validation rules, select option values, content locales and fallbacks, capabilities, auth settings and plugin configuration.

func (*Manifest) UnmarshalJSON

func (manifest *Manifest) UnmarshalJSON(encoded []byte) error

UnmarshalJSON replaces a manifest only after Parse validates the complete encoded value.

type NestedField

type NestedField struct {
	Fields            []Field              `json:"fields"`
	MinRows           int                  `json:"minRows,omitempty"`
	MaxRows           int                  `json:"maxRows,omitempty"`
	RowLabel          string               `json:"rowLabel,omitempty"`
	RowLabelComponent *FieldAdminComponent `json:"rowLabelComponent,omitempty"`
	RowLabels         *ArrayRowLabels      `json:"rowLabels,omitempty"`
	// contains filtered or unexported fields
}

NestedField contains recursively resolved child fields.

func (NestedField) ResolvedFields added in v0.2.0

func (n NestedField) ResolvedFields() []Field

type NumberField

type NumberField struct {
	Min  *float64 `json:"min,omitempty"`
	Max  *float64 `json:"max,omitempty"`
	Step *float64 `json:"step,omitempty"`
}

NumberField contains inclusive runtime bounds and the admin input step. Step is presentation metadata and is not a divisibility constraint.

type Plugin

type Plugin struct {
	Key        string            `json:"key"`
	GoPackage  string            `json:"goPackage,omitempty"`
	APIVersion uint32            `json:"apiVersion,omitempty"`
	Admin      *PluginAdmin      `json:"admin,omitempty"`
	FieldTypes []PluginFieldType `json:"fieldTypes,omitempty"`
	Endpoints  []PluginEndpoint  `json:"endpoints,omitempty"`
}

Plugin records one compiled plugin that participated in config resolution. A plugin's package version and Ridu compatibility range are checked when config is resolved but are not schema, so upgrading a plugin is never a data-model change.

type PluginAdmin

type PluginAdmin struct {
	Package        string   `json:"package"`
	Export         string   `json:"export"`
	APIVersion     uint32   `json:"apiVersion"`
	PairingVersion uint32   `json:"pairingVersion"`
	Routes         []string `json:"routes,omitempty"`
	Assets         []string `json:"assets,omitempty"`
}

PluginAdmin describes one statically imported admin package paired with a compiled backend plugin. It contains only public build metadata, never executable code or secrets.

type PluginEndpoint

type PluginEndpoint struct {
	Method  string `json:"method"`
	Path    string `json:"path"`
	Summary string `json:"summary"`
}

PluginEndpoint is the public manifest contract for one compiled endpoint.

type PluginField

type PluginField struct {
	EmbeddedTrees []EmbeddedTree  `json:"embeddedTrees,omitempty"`
	Key           string          `json:"key"`
	Config        json.RawMessage `json:"config"`
	ReferenceKeys []string        `json:"referenceKeys,omitempty"`
}

type PluginFieldType

type PluginFieldType struct {
	// EmbeddedTypes lists tree.case selectors supplying ordered generic payload type arguments.
	EmbeddedTypes     []string        `json:"embeddedTypes,omitempty"`
	Key               string          `json:"key"`
	TypeScriptPackage string          `json:"typescriptPackage"`
	TypeScriptOutput  string          `json:"typescriptOutput"`
	TypeScriptInput   string          `json:"typescriptInput"`
	TypeScriptWhere   string          `json:"typescriptWhere,omitempty"`
	GoPackage         string          `json:"goPackage,omitempty"`
	GoType            string          `json:"goType,omitempty"`
	JSONSchema        json.RawMessage `json:"jsonSchema,omitempty"`
}

PluginFieldType describes generated language types for one plugin field key.

type PointField

type PointField struct{}

PointField marks a [longitude, latitude] value.

type PreviewBreakpoint

type PreviewBreakpoint struct {
	Name              string            `json:"name"`
	Label             string            `json:"label"`
	LabelTranslations map[string]string `json:"labelTranslations,omitempty"`
	Width             int               `json:"width"`
	Height            int               `json:"height"`
}

PreviewBreakpoint describes one named live-preview viewport.

type PrimitiveListField added in v0.2.0

type PrimitiveListField struct {
	MinRows int `json:"minRows,omitempty"`
	MaxRows int `json:"maxRows,omitempty"`
}

PrimitiveListField constrains the number of values in one ordered text or number list. Items have no stored identity or nested field definitions. TextField and NumberField hold the corresponding per-item constraints.

type ReferenceDeleteAction

type ReferenceDeleteAction string

ReferenceDeleteAction is the resolved current-document policy applied when a relationship or upload target is hard deleted.

const (
	ReferenceDeleteNullify  ReferenceDeleteAction = "nullify"
	ReferenceDeleteRestrict ReferenceDeleteAction = "restrict"
	// ReferenceDeleteCascade deletes the owning document with its target. It
	// applies to singular, unlocalized references outside repeated rows.
	ReferenceDeleteCascade ReferenceDeleteAction = "cascade"
)

type RelationshipField

type RelationshipField struct {
	CollectionID   StableID              `json:"collectionId,omitempty"`
	CollectionSlug CollectionSlug        `json:"collectionSlug,omitempty"`
	Targets        []RelationshipTarget  `json:"targets,omitempty"`
	HasMany        bool                  `json:"hasMany,omitempty"`
	Polymorphic    bool                  `json:"polymorphic,omitempty"`
	OptionFilters  []RelationshipFilter  `json:"optionFilters,omitempty"`
	OnDelete       ReferenceDeleteAction `json:"onDelete"`
}

RelationshipField links to a resolved collection by stable ID and current slug.

type RelationshipFilter

type RelationshipFilter struct {
	CollectionSlug CollectionSlug `json:"collectionSlug,omitempty"`
	TargetPath     query.Path     `json:"targetPath"`
	Operator       string         `json:"operator,omitempty"`
	SourcePath     *query.Path    `json:"sourcePath,omitempty"`
	Value          *ScalarLiteral `json:"value,omitempty"`
}

RelationshipFilter derives an admin option predicate from document data.

type RelationshipTarget

type RelationshipTarget struct {
	CollectionID   StableID       `json:"collectionId"`
	CollectionSlug CollectionSlug `json:"collectionSlug"`
}

type ScalarLiteral added in v0.2.2

type ScalarLiteral struct {
	Type  ValueType `json:"type"`
	Value string    `json:"value"`
}

ScalarLiteral stores a canonical string, finite number, or boolean operand for visibility conditions and relationship filters.

func (ScalarLiteral) Decode added in v0.2.2

func (literal ScalarLiteral) Decode() (query.Value, error)

Decode validates the literal and returns its immutable query value. Numbers retain Go's floating-point parsing rules; booleans must be "true" or "false".

type SelectField

type SelectField struct {
	Options       []SelectOption `json:"options"`
	HasMany       bool           `json:"hasMany,omitempty"`
	DefaultValues []string       `json:"defaultValues,omitempty"`
}

SelectField contains the finite options for a select field.

type SelectOption added in v0.2.0

type SelectOption struct {
	Value             string            `json:"value"`
	Label             string            `json:"label"`
	LabelTranslations map[string]string `json:"labelTranslations,omitempty"`
}

SelectOption is one normalized select value and label.

type SlugField

type SlugField struct {
	SourcePath query.Path `json:"sourcePath"`
}

SlugField derives a normalized URL segment from one non-repeated string field. The operation engine remains authoritative; the admin mirrors this contract.

type Snapshot

type Snapshot struct {
	Version     Version      `json:"version"`
	Application Application  `json:"application"`
	Blocks      []BlockType  `json:"blocks,omitempty"`
	Collections []Collection `json:"collections"`
	Globals     []Global     `json:"globals,omitempty"`
	Plugins     []Plugin     `json:"plugins"`
}

Snapshot is a detached, serializable view of a Manifest.

type StableID

type StableID string

StableID is a deterministic internal schema identity. Migration artifacts record continuity when an authored collection slug or field path changes.

func PlacementFieldID added in v0.2.0

func PlacementFieldID(resource StableID, path []string) StableID

PlacementFieldID derives the stable ID of a field placed at canonical path segments beneath a resource, so every placement of a block definition has its own persistence identity.

type TextField

type TextField struct {
	MinLength *int       `json:"minLength,omitempty"`
	MaxLength *int       `json:"maxLength,omitempty"`
	Slug      *SlugField `json:"slug,omitempty"`
}

TextField contains inclusive Unicode code-point length constraints and optional first-class slug behavior while retaining ordinary text storage.

type UIField

type UIField struct{}

UIField marks presentation-only content omitted from document values.

type UploadField

type UploadField struct {
	CollectionID   StableID              `json:"collectionId"`
	CollectionSlug CollectionSlug        `json:"collectionSlug"`
	HasMany        bool                  `json:"hasMany,omitempty"`
	OptionFilters  []RelationshipFilter  `json:"optionFilters,omitempty"`
	OnDelete       ReferenceDeleteAction `json:"onDelete"`
}

UploadField references exactly one upload-enabled collection.

type UploadSettings

type UploadSettings struct {
	MaxFileSize int64       `json:"maxFileSize"`
	MimeTypes   []string    `json:"mimeTypes"`
	Private     bool        `json:"private"`
	ImageSizes  []ImageSize `json:"imageSizes,omitempty"`
	// MaxImageDimension is the largest width or height a stored JPEG or PNG
	// original keeps; zero keeps originals at their uploaded size.
	MaxImageDimension int `json:"maxImageDimension,omitempty"`
}

UploadSettings defines collection-owned media validation and delivery.

type ValidationError

type ValidationError struct {
	Issues []Issue `json:"issues"`
}

ValidationError contains every schema issue found during one deterministic validation pass.

func NewValidationError

func NewValidationError(issues []Issue) *ValidationError

NewValidationError copies issues into an inspectable validation error.

func (*ValidationError) Error

func (validationError *ValidationError) Error() string

type ValueType

type ValueType string

ValueType is the finite generated output vocabulary for computed fields.

const (
	ValueTypeString  ValueType = "string"
	ValueTypeNumber  ValueType = "number"
	ValueTypeBoolean ValueType = "boolean"
	ValueTypeJSON    ValueType = "json"
)

type Version

type Version uint32

Version is the schema manifest format version. It changes independently from the Ridu binary version.

const CurrentVersion Version = 1

CurrentVersion is the manifest format produced and accepted by this build.

type VersionSettings

type VersionSettings struct {
	Drafts                  bool  `json:"drafts"`
	MaxPerDocument          int   `json:"maxPerDocument"`
	AutosaveIntervalSeconds int64 `json:"autosaveIntervalSeconds"`
}

VersionSettings defines drafts, snapshot retention, autosave, and optimistic-revision behavior for one collection.

type VirtualField

type VirtualField struct {
	ValueType ValueType `json:"valueType"`
}

VirtualField describes the serialized type of an executable computed value.

Jump to

Keyboard shortcuts

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