Documentation
¶
Index ¶
- Constants
- Variables
- func AddClassList(classes []string, items []string) []string
- func AddClasses(classes []string, items string) []string
- func AddSingleClass(classes []string, item string) []string
- func Attr(name string, value any) template.HTMLAttr
- func Attrs(attrs map[string]string) template.HTMLAttr
- func AttrsAny(attrs map[string]any) template.HTMLAttr
- func AttrsSwitch(attrs any) template.HTMLAttr
- func BuildAPIErrorResponse(err error) httperrors.Interface
- func CanonicalEmail(email string) string
- func CanonicalPhone(number string) string
- func ClientNetworkingError(err error) error
- func DecodeFlashIntoRC(rc *RC)
- func DetermineMIMEType(r *http.Request) string
- func EmailRateLimitingKey(email string) string
- func FacebookMessengerSendLinkURL(appID, link, redirectURL string) string
- func FacebookShareLinkURL(appID, link, redirectURL string) string
- func FlakeIDType() reflect.Type
- func GracefulShutdown(gracePeriod time.Duration, graceful func(ctx context.Context) error, ...)
- func HTMLify(v any) template.HTML
- func HTMLifyMultiparString(text string) template.HTML
- func HTMLifyMultiparValue(v any) template.HTML
- func HTMLifyString(text string) template.HTML
- func HTTPStatusCode(err error) int
- func InterceptShutdownSignals(shutdown func())
- func IsAndroidRequest(r *http.Request) bool
- func IsAndroidUA(ua string) bool
- func IsBrowserCripplingCrossOriginCookies(r *http.Request) bool
- func IsClientNetworkingError(err error) bool
- func IsFacebookUA(ua string) bool
- func IsGetOrHead(r *http.Request) bool
- func IsMobileRequest(r *http.Request) bool
- func IsMobileUA(ua string) bool
- func IsSafariRequest(r *http.Request) bool
- func IsSafariUA(ua string) bool
- func IsUndefined(v any) bool
- func JoinClassList(classes []string) string
- func JoinClassStrings(items ...string) string
- func JoinClasses(items ...any) string
- func JoinInlineCSS(a, b string) string
- func Main(ge *Configuration)
- func NewPanic(errValue any) error
- func PartialRenderingError(templ string, cause error) error
- func PlusToPercent20(s string) string
- func PushPartial(rc RCish, vd *ViewData, elementID string, ch mvplive.Channel, ...)
- func RandomAlpha(n int) string
- func RandomBytes(len int) []byte
- func RandomDigits(n int) string
- func RandomHex(len int) string
- func RandomPassword(n int) string
- func ReadAPIRequest(r *http.Request, in any) error
- func RecoveredError(e any) error
- func RegisterBuiltinUtilityViewHelpers(m template.FuncMap)
- func RenderPartial(rc *RC, vd *ViewData) template.HTML
- func RenderPartialTo(wr io.Writer, rc *RC, vd *ViewData)
- func RequireGetOrHead(w http.ResponseWriter, r *http.Request) bool
- func RunningMigrationName(requestID string) string
- func SMSLinkURI(phone, body string, ua string) string
- func SafeCall(f func() error) (err error)
- func SafeCall01[R1 any](f func() (R1, error)) (r1 R1, err error)
- func SafeCall11[A1, R1 any](f func(a1 A1) (R1, error), a1 A1) (r1 R1, err error)
- func SafeCall21[A1, A2, R1 any](f func(a1 A1, a2 A2) (R1, error), a1 A1, a2 A2) (r1 R1, err error)
- func SkipPanicStackIf(f func(error) bool)
- func Stringify(v any) string
- func TweetIntentURL(body string, linkURL string) string
- func ValueDefault[T any](v T) func(val *Val[T])
- func ValueDep[T any](deps ...AnyVal) func(val *Val[T])
- func ValueInitializer[T any](f func() T) func(val *Val[T])
- func ValueZeroInit[T any](val *Val[T])
- func ViewRenderingError(templ string, cause error) error
- func WhatsappSendURL(body string, mobile bool) string
- func WriteAPIResponse(w http.ResponseWriter, out any, indented bool)
- func WriteFileAtomic(path string, data []byte, perm fs.FileMode) (err error)
- func WriteMethodNotAllowed(w http.ResponseWriter)
- func WritePlainError(w http.ResponseWriter, err error)
- type AnyVal
- type App
- func (app *App) AuthenticateRequestMiddleware(rc *RC) (any, error)
- func (app *App) Close()
- func (app *App) DB() *edb.DB
- func (app *App) DecodeAuthToken(rc *RC, token string) error
- func (app *App) DefaultHTTPClient() *http.Client
- func (app *App) Enqueue(rc RCish, kind *mvpjobs.Kind, in mvpjobs.Params) *mvpjobs.Job
- func (app *App) EnqueueEphemeral(kind *mvpjobs.Kind, name string, f func(rc *RC) error)
- func (app *App) EvalTemplate(templateName string, data any) (template.HTML, error)
- func (app *App) ExecTemplate(w io.Writer, templateName string, data any) error
- func (app *App) FileProvider(resourceURI string, rc *RC) (FileProvider, string)
- func (app *App) FileURL(resourceURI string, rc *RC, opt mvpm.URLOption) string
- func (app *App) Initialize(settings *Settings, opt AppOptions)
- func (app *App) Job(txish edb.Txish, kind *mvpjobs.Kind, name string) *mvpjobs.Job
- func (app *App) JobImpl(kind *mvpjobs.Kind)
- func (app *App) MakeAuthToken(sessID flake.ID, actorRef mvpm.Ref, validity time.Duration) string
- func (app *App) MethodImpl(method *mvprpc.Method, impl any)
- func (app *App) NewHTTPRequestRC(w http.ResponseWriter, r bunrouter.Request) *RC
- func (app *App) NewID() flake.ID
- func (app *App) Now() time.Time
- func (app *App) PublishMsg(lc flogger.Context, ch mvplive.Channel, msg *mvplive.Msg)
- func (app *App) PublishTurbo(lc flogger.Context, ch mvplive.Channel, ep mvplive.Envelope, ...)
- func (app *App) RateLimiters(preset RateLimitPreset) map[RateLimitGranularity]*RateLimiter
- func (app *App) ReadFile(resourceURI string, rc *RC) ([]byte, error)
- func (app *App) Redirect(name string, extras ...any) *Redirect
- func (app *App) Reenqueue(rc RCish, kind *mvpjobs.Kind, j *mvpjobs.Job, in mvpjobs.Params, force bool)
- func (app *App) Render(lc flogger.Context, data *ViewData) ([]byte, error)
- func (app *App) RenderForm(rc *RC, form *forms.Form) template.HTML
- func (app *App) RunJob(ctx context.Context, kind *mvpjobs.Kind, params mvpjobs.Params) error
- func (app *App) RunPendingJobs(ctx context.Context) int
- func (app *App) SendEmail(rc *RC, msg *Email)
- func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (app *App) SetNewKeyOnRow(row any) bool
- func (app *App) StartEphemeralJobWorkers(ctx context.Context, count int, quitf func(err error))
- func (app *App) StartJobWorkers(ctx context.Context, count int, quitf func(err error))
- func (app *App) StaticFS() fs.FS
- func (app *App) Subscribe(ctx context.Context, lc flogger.Context, w http.ResponseWriter, ...)
- func (app *App) URL(name string, extras ...URLOption) string
- func (app *App) WriteAPIError(w http.ResponseWriter, err error)
- type AppBehaviors
- type AppInit
- type AppOptions
- type Auth
- type CacheBustingSession
- type CallRegistry
- type Configuration
- type DebugOutput
- type DomainRouter
- type Email
- type EphemeralJob
- type EphemeralJobQueue
- type ErrHandler
- type ExpandableObject
- type ExpandableType
- type FileProvider
- type Flash
- type GoRuntimeSettings
- type Hooks
- func (h *Hooks) BustCache(f func(rc *RC, key any) bool)
- func (h *Hooks) CloseApp(f func(app *App))
- func (h *Hooks) CloseRC(f func(app *App, rc *RC))
- func (h *Hooks) DBChange(f func(rc *RC, chg *edb.Change))
- func (h *Hooks) DomainRoutes(f func(app *App, b *DomainRouter))
- func (h *Hooks) Helpers(f func(m template.FuncMap))
- func (h *Hooks) InitApp(f func(app *App, init *AppInit))
- func (h *Hooks) InitDB(f func(app *App, rc *RC))
- func (h *Hooks) InitRC(f func(app *App, rc *RC))
- func (h *Hooks) JWTTokenKey(f func(rc *RC, c *TokenDecoding) error)
- func (h *Hooks) MakeRowKey(f func(app *App, tbl *edb.Table) any)
- func (h *Hooks) Middleware(f func(r Router))
- func (h *Hooks) Migrate(f func(app *App, b *MigrationBuilder))
- func (h *Hooks) PostAuth(f func(app *App, rc *RC) error)
- func (h *Hooks) ResetAuth(f func(app *App, rc *RC))
- func (h *Hooks) SiteRoutes(site *Site, f func(b *RouteBuilder))
- func (h *Hooks) URLGen(f func(app *App, g *URLGen))
- func (h *Hooks) URLGenOption(f func(app *App, g *URLGen, option string) bool)
- type JobImpl
- type JobRegistry
- type MethodImpl
- type MigrationBuilder
- type Module
- type Mood
- type Msg
- type Panic
- type PathParamsMapAny
- type PathParamsMapStr
- type RC
- func (rc *RC) ActorRef() mvpm.Ref
- func (rc *RC) App() *App
- func (rc *RC) AppendLogPrefix(buf *bytes.Buffer)
- func (rc *RC) AppendLogSuffix(buf *bytes.Buffer)
- func (rc *RC) Auth() Auth
- func (rc *RC) BaseApp() *App
- func (rc *RC) BaseRC() *RC
- func (rc *RC) BustCache(keys ...any)
- func (rc *RC) Close()
- func (rc *RC) ConfigureHTTPRequest(r *httpcall.Request, logPrefix string)
- func (rc *RC) DBTx() *edb.Tx
- func (rc *RC) Deadline() (deadline time.Time, ok bool)
- func (rc *RC) DefaultPathParams() PathParamsMapStr
- func (rc *RC) DeleteAuthCookie()
- func (rc *RC) Done() <-chan struct{}
- func (rc *RC) DoneReading()
- func (rc *RC) Err() error
- func (rc *RC) Fail(err error)
- func (rc *RC) FileURL(resourceURI string, opt mvpm.URLOption) string
- func (rc *RC) HandleForm(form *forms.Form) bool
- func (rc *RC) InTx(affinity mvpm.StoreAffinity, f func() error) error
- func (rc *RC) IsInWriteTx() bool
- func (rc *RC) IsLoggedIn() bool
- func (rc *RC) LogTo(buf *strings.Builder)
- func (rc *RC) Logf(format string, args ...any)
- func (rc *RC) MustRead(f func())
- func (rc *RC) MustWrite(f func())
- func (rc *RC) NewID() flake.ID
- func (rc *RC) Now() time.Time
- func (rc *RC) ReadFile(resourceURI string) ([]byte, error)
- func (rc *RC) Redirect(name string, extras ...any) *Redirect
- func (rc *RC) RedirectBack() *Redirect
- func (rc *RC) RefreshNowTime()
- func (rc *RC) RouteName() string
- func (rc *RC) SendSSE(msg *sse.Msg)
- func (rc *RC) SendSSETurboStream(id uint64, f func(stream *hotwired.Stream))
- func (rc *RC) SessionID() flake.ID
- func (rc *RC) SetAuthCookie(token string, validity time.Duration)
- func (rc *RC) SetAuthUsingCookie(auth Auth)
- func (rc *RC) SetCookie(cookie *http.Cookie)
- func (rc *RC) TryRead(f func() error) error
- func (rc *RC) TryWrite(f func() error) error
- func (rc *RC) Value(key any) any
- type RCish
- type RateLimitGranularity
- type RateLimitPreset
- type RateLimitSettings
- type RateLimiter
- type RawOutput
- type Redirect
- func (redir *Redirect) EffectivePath() string
- func (redir *Redirect) EffectiveStatusCode() int
- func (redir *Redirect) Permanent() *Redirect
- func (redir *Redirect) SameMethod() *Redirect
- func (redir *Redirect) WithFlash(flash *Flash) *Redirect
- func (redir *Redirect) WithValue(key, value string) *Redirect
- func (redir *Redirect) WithValues(values url.Values) *Redirect
- type RenderData
- func (d *RenderData) ArgsByPrefix(prefix string) map[string]any
- func (d *RenderData) Bind(data any, args ...any) *RenderData
- func (d *RenderData) HTMLSafeString(name string) (template.HTML, bool)
- func (d *RenderData) MapSA(name string) (map[string]any, bool)
- func (d *RenderData) PopHTMLSafeString(name string) (template.HTML, bool)
- func (d *RenderData) PopMapSA(name string) (map[string]any, bool)
- func (d *RenderData) PopString(name string) (string, bool)
- func (d *RenderData) PopValue(name string) (any, bool)
- func (d *RenderData) String(name string) (string, bool)
- func (d *RenderData) Value(name string) (any, bool)
- type RenderingError
- type ResponseHandled
- type Route
- func (r *Route) BodyParamNames() []string
- func (r *Route) Description() string
- func (r *Route) IsIdempotent() bool
- func (r *Route) Method() string
- func (route *Route) Mutator()
- func (c *Route) OnError(f ErrHandler)
- func (r *Route) Path() string
- func (r *Route) PathParams() []string
- func (c *Route) RateLimit(preset RateLimitPreset)
- func (r *Route) RouteName() string
- func (c *Route) Use(middleware any)
- func (c *Route) UseIn(slot string, middleware any)
- type RouteBuilder
- func (g *RouteBuilder) Func(f any, options ...RouteOption) *Route
- func (g *RouteBuilder) Group(path string, f func(b *RouteBuilder))
- func (c *RouteBuilder) OnError(f ErrHandler)
- func (c *RouteBuilder) RateLimit(preset RateLimitPreset)
- func (g *RouteBuilder) Raw() *bunrouter.Group
- func (g *RouteBuilder) Route(routeName string, methodAndPath string, f any, options ...RouteOption) *Route
- func (g *RouteBuilder) RouteForm(routeName string, path string, f any, options ...RouteOption) *Route
- func (g *RouteBuilder) Static(path string, cm mvphttp.CacheMode, cors *cors.CORS)
- func (c *RouteBuilder) Use(middleware any)
- func (c *RouteBuilder) UseIn(slot string, middleware any)
- type RouteFlagOption
- type RouteOption
- type Router
- type Secrets
- func (secrets Secrets) Optional(name string, val interface{ ... }) bool
- func (secrets Secrets) OptionalNamedKeySet(name string, keys *mvpm.NamedKeySet, minKeyLen, maxKeyLen int) bool
- func (secrets Secrets) Required(name string, val interface{ ... })
- func (secrets Secrets) RequiredNamedKeySet(name string, keys *mvpm.NamedKeySet, minKeyLen, maxKeyLen int)
- type Settings
- type Site
- type SiteData
- type SkipStackOnPanic
- type TokenDecoding
- type URLGen
- type URLOption
- type Val
- type ValueSet
- type ViewData
Constants ¶
const ( MoodNeutral = Mood(iota) MoodSuccess MoodFailure MoodSubtle )
const ( RateLimitPresetNone = RateLimitPreset("none") RateLimitPresetDefaultWebRead = RateLimitPreset("web.r") RateLimitPresetDefaultWebWrite = RateLimitPreset("web.w") RateLimitPresetDefaultAPIRead = RateLimitPreset("api.r") RateLimitPresetDefaultAPIWrite = RateLimitPreset("api.w") RateLimitPresetSpam = RateLimitPreset("spam") RateLimitPresetAuthentication = RateLimitPreset("auth") RateLimitPresetDangerous = RateLimitPreset("danger") )
const ( RateLimitGranularityApp = RateLimitGranularity("app") RateLimitGranularityIP = RateLimitGranularity("ip") RateLimitGranularityUser = RateLimitGranularity("user") RateLimitGranularityKey = RateLimitGranularity("key") )
const ( MwSlotRateLimitAdjustment = "ratelimitconf" MwSlotRateLimiter = "ratelimit" )
const (
MigrationRequestIDPrefix = "init:migration:"
)
Variables ¶
var ( // Now is the start time of a request. For short requests, it should be the Now // value for all processing that happens inside. Can be mocked. Now = Value[time.Time]("now") // WallStart is an unmocked start time of the request for RealStartTime = Value[time.Time]("real_start_time") )
var ( AppContextKey = appContextKeyType{} RCContextKey = rcContextKeyType{} )
var ( ErrTooManyRequests = httperrors.Define(http.StatusTooManyRequests, "too_many_requests") ErrInvalidToken = httperrors.Define(http.StatusUnauthorized, "invalid_token") ErrForbidden = httperrors.Define(http.StatusForbidden, "forbidden") ErrAPIInvalidMethod = httperrors.Define(http.StatusMethodNotAllowed, "invalid_http_method") ErrAPIUnsupportedContentType = httperrors.Define(http.StatusUnsupportedMediaType, "invalid_content_type") ErrAPIInvalidJSON = httperrors.Define(http.StatusBadRequest, "invalid_json") ErrAPIUnknownMethod = httperrors.Define(http.StatusNotFound, "unknown_method") ErrPanic = httperrors.Define(http.StatusInternalServerError, "internal_server_error") )
var ( BaseSettings = expandable.NewBase[Settings](baseSchema, "settings") BaseApp = expandable.NewBase[App](baseSchema, "app") BaseRC = expandable.NewBase[RC](baseSchema, "rc") )
var ( NoSite = NewSite("none") DefaultSite = NewSite("default") )
var (
Absolute = mvpm.NewURLOption("absolute")
)
var (
GoCtx = Value[context.Context]("goctx")
)
Functions ¶
func AddClassList ¶
func AddClasses ¶
func AddSingleClass ¶
func AttrsSwitch ¶ added in v0.2.0
func BuildAPIErrorResponse ¶
func BuildAPIErrorResponse(err error) httperrors.Interface
func CanonicalEmail ¶
CanonicalEmail returns an email suitable for unique checks.
func CanonicalPhone ¶
CanonicalPhone returns an phone number suitable for unique checks.
func ClientNetworkingError ¶
func DecodeFlashIntoRC ¶ added in v0.2.2
func DecodeFlashIntoRC(rc *RC)
func DetermineMIMEType ¶
func EmailRateLimitingKey ¶
EmailRateLimitingKey is a slightly paranoid function that maps emails into string keys to use for rate limiting.
func FacebookMessengerSendLinkURL ¶ added in v0.2.2
func FacebookShareLinkURL ¶ added in v0.2.2
func FlakeIDType ¶
func GracefulShutdown ¶
func GracefulShutdown(gracePeriod time.Duration, graceful func(ctx context.Context) error, forceful func())
gracefulShutdown tries to do a graceful shutdown, but abandons the attempt and falls back to forceful shutdown after a timeout.
func HTMLifyMultiparString ¶ added in v0.2.2
func HTMLifyMultiparValue ¶ added in v0.2.2
func HTMLifyString ¶ added in v0.2.0
func HTTPStatusCode ¶
func InterceptShutdownSignals ¶
func InterceptShutdownSignals(shutdown func())
func IsAndroidRequest ¶ added in v0.2.1
func IsAndroidUA ¶ added in v0.2.1
func IsBrowserCripplingCrossOriginCookies ¶ added in v0.3.0
func IsClientNetworkingError ¶
func IsFacebookUA ¶ added in v0.2.2
func IsGetOrHead ¶ added in v0.2.2
func IsMobileRequest ¶ added in v0.2.1
func IsMobileUA ¶ added in v0.2.1
func IsSafariRequest ¶ added in v0.3.0
func IsSafariUA ¶ added in v0.3.0
func IsUndefined ¶
func JoinClassList ¶
func JoinClassStrings ¶ added in v0.2.1
func JoinClasses ¶
func JoinInlineCSS ¶ added in v0.2.1
func Main ¶
func Main(ge *Configuration)
func PartialRenderingError ¶ added in v0.2.2
func PlusToPercent20 ¶ added in v0.2.1
func PushPartial ¶ added in v0.2.1
func RandomAlpha ¶
func RandomBytes ¶
func RandomDigits ¶
func RandomPassword ¶ added in v0.2.2
func RecoveredError ¶
func RegisterBuiltinUtilityViewHelpers ¶ added in v0.2.0
func RequireGetOrHead ¶ added in v0.2.2
func RequireGetOrHead(w http.ResponseWriter, r *http.Request) bool
func RunningMigrationName ¶ added in v0.3.2
func SMSLinkURI ¶ added in v0.2.1
func SafeCall01 ¶ added in v0.2.2
func SafeCall11 ¶ added in v0.2.2
func SafeCall21 ¶ added in v0.2.2
func SkipPanicStackIf ¶ added in v0.2.2
func TweetIntentURL ¶ added in v0.2.1
func ValueDefault ¶
ValueDefault is an option to pass to Value.
func ValueDep ¶
ValueDep is an option to pass to Value. It signals that this value should be initialized after those other values.
func ValueInitializer ¶
ValueInitializer is an option to pass to Value.
func ValueZeroInit ¶
ValueZeroInit is an option to pass to Value.
func ViewRenderingError ¶ added in v0.2.2
func WhatsappSendURL ¶ added in v0.2.1
func WriteAPIResponse ¶
func WriteAPIResponse(w http.ResponseWriter, out any, indented bool)
func WriteMethodNotAllowed ¶ added in v0.2.2
func WriteMethodNotAllowed(w http.ResponseWriter)
func WritePlainError ¶ added in v0.2.2
func WritePlainError(w http.ResponseWriter, err error)
Types ¶
type App ¶
type App struct { ValueSet DBSchema edb.Schema JobSchema *mvpjobs.Schema Configuration *Configuration Settings *Settings Hooks Hooks BaseURL *url.URL IPForwarding *mvputil.IPForwarding // contains filtered or unexported fields }
func (*App) AuthenticateRequestMiddleware ¶
func (*App) DefaultHTTPClient ¶ added in v0.3.10
func (*App) EnqueueEphemeral ¶
func (*App) EvalTemplate ¶
func (*App) ExecTemplate ¶
func (*App) FileProvider ¶
func (app *App) FileProvider(resourceURI string, rc *RC) (FileProvider, string)
func (*App) Initialize ¶
func (app *App) Initialize(settings *Settings, opt AppOptions)
func (*App) MakeAuthToken ¶
func (*App) NewHTTPRequestRC ¶
func (*App) PublishMsg ¶
func (*App) PublishTurbo ¶
func (*App) RateLimiters ¶
func (app *App) RateLimiters(preset RateLimitPreset) map[RateLimitGranularity]*RateLimiter
func (*App) Redirect ¶
Redirect returns a response object that redirects to a given route. Status code defaults to 303 See Other. Supply map[string]string or pairs of (key string, value string) arguments to supply path parameters for the route. Supply url.Values to add query parameters. Supply Absolute flag to use an absolute URL.
func (*App) SetNewKeyOnRow ¶
func (*App) StartEphemeralJobWorkers ¶
func (*App) StartJobWorkers ¶
func (*App) URL ¶
URL generates a relative (default) or absolute URL based on a named route. Supply map[string]string or pairs of (key string, value string) arguments to supply path parameters for the route. Supply url.Values to add query parameters. Supply Absolute flag to return an absolute URL.
func (*App) WriteAPIError ¶
func (app *App) WriteAPIError(w http.ResponseWriter, err error)
type AppBehaviors ¶
type AppInit ¶ added in v0.3.0
type AppInit struct {
// contains filtered or unexported fields
}
func (*AppInit) MonitorDBChanges ¶ added in v0.3.0
func (init *AppInit) MonitorDBChanges(tbl *edb.Table, flags edb.ChangeFlags)
type AppOptions ¶
type AppOptions struct { Context context.Context Logf func(format string, v ...interface{}) TestTransport http.RoundTripper }
type CacheBustingSession ¶ added in v0.3.0
type CallRegistry ¶
type Configuration ¶
type Configuration struct { Envs map[string][]string Preinstall func(settings *Settings) Install func(settings *Settings) BuildCommit string BuildVer string EmbeddedConfig []byte EmbeddedSecrets string EmbeddedStaticFS embed.FS EmbeddedViewsFS embed.FS ConfigFileName string SecretsFileName string StaticSubdir string ViewsSubdir string LocalDevAppRoot string FallbackFormID string Modules []*Module LoadSecrets func(*Settings, Secrets) Types map[mvpm.Type][]string AuthTokenCookieName string AuthTokenKeys mvpm.NamedKeySet }
func (*Configuration) ValidEnvs ¶
func (ge *Configuration) ValidEnvs() []string
type DomainRouter ¶
type DomainRouter struct {
// contains filtered or unexported fields
}
func (*DomainRouter) HandleFunc ¶
func (router *DomainRouter) HandleFunc(domain string, h func(http.ResponseWriter, *http.Request))
func (*DomainRouter) Site ¶
func (router *DomainRouter) Site(domain string, site *Site)
func (*DomainRouter) ValidDomains ¶
func (router *DomainRouter) ValidDomains() []string
type EphemeralJobQueue ¶
type EphemeralJobQueue struct {
// contains filtered or unexported fields
}
type ExpandableObject ¶
type ExpandableObject interface { // ValueAt(idx int) any ValueSet() ValueSet }
type ExpandableType ¶
type ExpandableType struct {
StoredValues []AnyVal
}
type FileProvider ¶
type Flash ¶ added in v0.2.2
type Flash struct { Msg *Msg `json:"m,omitempty"` Action string `json:"a,omitempty"` Target string `json:"t,omitempty"` ScrollTarget string `json:"s,omitempty"` Extras map[string]any `json:"e,omitempty"` }
func DecodeFlashFromQuery ¶ added in v0.2.2
func FailureMsg ¶
func NeutralMsg ¶
func SuccessMsg ¶
func (*Flash) JSONString ¶ added in v0.2.2
func (*Flash) WithAction ¶ added in v0.2.2
type GoRuntimeSettings ¶ added in v0.3.0
func (*GoRuntimeSettings) Apply ¶ added in v0.3.0
func (rs *GoRuntimeSettings) Apply()
type Hooks ¶
type Hooks struct {
// contains filtered or unexported fields
}
func (*Hooks) DomainRoutes ¶
func (h *Hooks) DomainRoutes(f func(app *App, b *DomainRouter))
func (*Hooks) JWTTokenKey ¶
func (h *Hooks) JWTTokenKey(f func(rc *RC, c *TokenDecoding) error)
func (*Hooks) Middleware ¶
func (*Hooks) Migrate ¶ added in v0.2.1
func (h *Hooks) Migrate(f func(app *App, b *MigrationBuilder))
func (*Hooks) SiteRoutes ¶
func (h *Hooks) SiteRoutes(site *Site, f func(b *RouteBuilder))
type JobRegistry ¶
type MethodImpl ¶
type MigrationBuilder ¶ added in v0.2.1
type MigrationBuilder struct {
// contains filtered or unexported fields
}
func (*MigrationBuilder) Draft ¶ added in v0.2.1
func (b *MigrationBuilder) Draft(id mvpm.MigrationID, name string, handler func(rc *RC))
func (*MigrationBuilder) Run ¶ added in v0.2.1
func (b *MigrationBuilder) Run(id mvpm.MigrationID, name string, handler func(rc *RC))
func (*MigrationBuilder) Stale ¶ added in v0.2.1
func (b *MigrationBuilder) Stale(id mvpm.MigrationID, name string, handler func(rc *RC))
type Mood ¶
type Mood int
func (*Mood) DecodeMsgpack ¶ added in v0.2.2
func (Mood) EncodeMsgpack ¶ added in v0.2.2
func (Mood) MarshalText ¶ added in v0.2.2
func (*Mood) UnmarshalText ¶ added in v0.2.2
type Msg ¶
type Msg struct { Text string `json:"t,omitempty"` Link string `json:"l,omitempty"` LinkText string `json:"lt,omitempty"` Mood Mood `json:"m,omitempty"` }
func RawFailureMsg ¶ added in v0.2.2
func RawNeutralMsg ¶ added in v0.2.2
func RawSubtleMsg ¶ added in v0.2.2
func RawSuccessMsg ¶ added in v0.2.2
type PathParamsMapAny ¶
type PathParamsMapStr ¶ added in v0.2.1
type RC ¶
type RC struct { RequestID string Start time.Time // ACTUAL time of request start RealIPStr string RealHost string RealTLS bool Route *Route Request bunrouter.Request RespWriter http.ResponseWriter Flash *Flash SetCookies []*http.Cookie RateLimitPreset RateLimitPreset RateLimitKey string // contains filtered or unexported fields }
RC stands for Request Context, and holds all the things we want to associate with a request.
RC carries:
- Transaction
- Authentication
- context.Context
- Logging context
- Current HTTP request info
- HTTP response side-channel bits (cookies at the moment)
- Matched route or call info
- Timing information
- Anything else that middleware needs to read or write
Why this instead of stuffing things into context.Context? Mostly because it's more explicit, typed, doesn't require O(N) lookup to have N values, and doesn't require an allocation per value. If anything, you'd put *RC into context.Context, not individual values, so you'd need this type anyway.
RC doesn't just wrap HTTP requests; it is also used by jobs and one-off code. Similar to context.Context, it's a nice way to propagate transactions, authentication and other stuff throughout the routing/call handling machinery without every function knowing about and dealing with individual values.
This type also carries any data you want to communicate between middleware and HTTP handlers. At the very least, it carries concrete authentication data, but also things like tenant ref in multi-tenant applications, etc. As one example, we want to be able to implement Rails-like “flash” middleware, so RC needs to carry input/output cookies AND any resulting flash data.
As such, this type is meant to be customized for a particular application.
func OptionalRCFrom ¶ added in v0.3.9
func (*RC) AppendLogPrefix ¶
func (*RC) AppendLogSuffix ¶
func (*RC) ConfigureHTTPRequest ¶ added in v0.3.9
func (*RC) DefaultPathParams ¶
func (rc *RC) DefaultPathParams() PathParamsMapStr
func (*RC) DeleteAuthCookie ¶
func (rc *RC) DeleteAuthCookie()
func (*RC) DoneReading ¶ added in v0.2.2
func (rc *RC) DoneReading()
func (*RC) InTx ¶ added in v0.2.2
func (rc *RC) InTx(affinity mvpm.StoreAffinity, f func() error) error
func (*RC) IsInWriteTx ¶ added in v0.3.0
func (*RC) IsLoggedIn ¶
func (*RC) RedirectBack ¶ added in v0.2.1
func (*RC) RefreshNowTime ¶ added in v0.2.2
func (rc *RC) RefreshNowTime()
func (*RC) SendSSETurboStream ¶ added in v0.2.2
func (*RC) SetAuthUsingCookie ¶
type RCish ¶ added in v0.2.1
type RCish interface { BaseRC() *RC BaseApp() *App DBTx() *edb.Tx Now() time.Time RefreshNowTime() IsLoggedIn() bool SessionID() flake.ID ActorRef() mvpm.Ref Auth() Auth InTx(affinity mvpm.StoreAffinity, f func() error) error TryRead(f func() error) error TryWrite(f func() error) error MustRead(f func()) MustWrite(f func()) DoneReading() flogger.Context }
type RateLimitGranularity ¶
type RateLimitGranularity string
type RateLimitPreset ¶
type RateLimitPreset string
type RateLimitSettings ¶
type RateLimiter ¶
type RateLimiter struct { Preset RateLimitPreset Settings RateLimitSettings // contains filtered or unexported fields }
type Redirect ¶
func (*Redirect) EffectivePath ¶ added in v0.2.2
func (*Redirect) EffectiveStatusCode ¶ added in v0.2.2
func (*Redirect) Permanent ¶
Permanent uses 308 Permanent Redirect for this redirect. Same HTTP method will be used for the redirected request.
Note that there is no permanent redirection code that is guaranteed to always use GET. 301 Moved Permanently may or may not do that and is not recommended.
func (*Redirect) SameMethod ¶
SameMethod uses 307 Temporary Redirect for this redirect. Same HTTP method will be used for the redirected request, unlike the default 303 See Other response which always redirects with a GET.
type RenderData ¶
func (*RenderData) ArgsByPrefix ¶
func (d *RenderData) ArgsByPrefix(prefix string) map[string]any
func (*RenderData) Bind ¶
func (d *RenderData) Bind(data any, args ...any) *RenderData
func (*RenderData) HTMLSafeString ¶
func (d *RenderData) HTMLSafeString(name string) (template.HTML, bool)
func (*RenderData) PopHTMLSafeString ¶
func (d *RenderData) PopHTMLSafeString(name string) (template.HTML, bool)
type RenderingError ¶ added in v0.2.2
func (*RenderingError) Error ¶ added in v0.2.2
func (err *RenderingError) Error() string
func (*RenderingError) SkipStackOnPanic ¶ added in v0.2.2
func (err *RenderingError) SkipStackOnPanic() bool
type ResponseHandled ¶
type ResponseHandled struct{}
type Route ¶
type Route struct {
// contains filtered or unexported fields
}
func (*Route) BodyParamNames ¶ added in v0.2.1
func (*Route) Description ¶
Description returns "callName method path"
func (*Route) IsIdempotent ¶
IsIdempotent whether the route is idempotent, which generally means the GET method, although some GET routes might be manually marked as non-idempotent via Route.Mutator().
func (*Route) OnError ¶
func (c *Route) OnError(f ErrHandler)
func (*Route) PathParams ¶
func (*Route) RateLimit ¶
func (c *Route) RateLimit(preset RateLimitPreset)
func (*Route) Use ¶
func (c *Route) Use(middleware any)
Use adds the given middleware to all future routes.
func (*Route) UseIn ¶
UseIn adds the given middleware under the given slot. If the slot is already occupied, overrides the middleware in the given slot (so that you, for example, can define a default authentication or CORS middleware, but override it for certain groups or routes). Use nil as middleware to override with nothing, or to reserve a slot position without assigning middlware yet.
type RouteBuilder ¶
type RouteBuilder struct {
// contains filtered or unexported fields
}
RouteBuilder helps to define named routes, and holds the path and middleware.
func (*RouteBuilder) Func ¶ added in v0.2.1
func (g *RouteBuilder) Func(f any, options ...RouteOption) *Route
func (*RouteBuilder) Group ¶
func (g *RouteBuilder) Group(path string, f func(b *RouteBuilder))
group defines a group of routes with a common prefix and/or middleware.
func (*RouteBuilder) OnError ¶
func (c *RouteBuilder) OnError(f ErrHandler)
func (*RouteBuilder) RateLimit ¶
func (c *RouteBuilder) RateLimit(preset RateLimitPreset)
func (*RouteBuilder) Raw ¶
func (g *RouteBuilder) Raw() *bunrouter.Group
func (*RouteBuilder) Route ¶
func (g *RouteBuilder) Route(routeName string, methodAndPath string, f any, options ...RouteOption) *Route
Route defines a named route. methodAndPath are space-separated.
The handler function must have func(rc *RC, in *SomeStruct) (output, error) signature, where output can be anything, but must be something that app.writeResponse accepts.
func (*RouteBuilder) RouteForm ¶ added in v0.2.2
func (g *RouteBuilder) RouteForm(routeName string, path string, f any, options ...RouteOption) *Route
func (*RouteBuilder) Use ¶
func (c *RouteBuilder) Use(middleware any)
Use adds the given middleware to all future routes.
func (*RouteBuilder) UseIn ¶
UseIn adds the given middleware under the given slot. If the slot is already occupied, overrides the middleware in the given slot (so that you, for example, can define a default authentication or CORS middleware, but override it for certain groups or routes). Use nil as middleware to override with nothing, or to reserve a slot position without assigning middlware yet.
type RouteFlagOption ¶ added in v0.2.2
type RouteFlagOption int
const ( ReadOnly RouteFlagOption = 1 + iota Mutator IdempotentMutator )
type RouteOption ¶
type RouteOption = any
type Router ¶
type Router interface { Use(middleware any) UseIn(slot string, middleware any) OnError(f ErrHandler) RateLimit(preset RateLimitPreset) }
type Secrets ¶
func (Secrets) OptionalNamedKeySet ¶
func (Secrets) RequiredNamedKeySet ¶
func (secrets Secrets) RequiredNamedKeySet(name string, keys *mvpm.NamedKeySet, minKeyLen, maxKeyLen int)
type Settings ¶
type Settings struct { Env string Configuration *Configuration GoRuntimeSettings // Configuration options LocalOverridesFile string AutoEncryptSecrets bool KeyringFile string // HTTP server options BindAddr string BindPort int ForwardingProxyCIDRs string // job options WorkerCount int EphemeralWorkerCount int EphemeralQueueMaxSize int // app options AppName string // user-visible app name AppID string // unchangeable internal name for various identification purposes BaseURL string RateLimits map[RateLimitPreset]map[RateLimitGranularity]RateLimitSettings MaxRateLimitRequestDelay jsonext.Duration AppBehaviors DataDir string VerboseDB bool Postmark postmark.Credentials PostmarkDefaultMessageStream string EmailDefaultFrom string EmailDefaultLayout string JWTIssuers []string // Issuer and Audience for this app's tokens }
func LoadConfig ¶
func LoadConfig(ge *Configuration, env string, installHook func(*Settings)) *Settings
type SkipStackOnPanic ¶ added in v0.2.2
type SkipStackOnPanic interface {
SkipStackOnPanic() bool
}
type TokenDecoding ¶
type TokenDecoding struct { Now time.Time Token jwt.Token Claims jwt.Claims KeyID string Issuer string // contains filtered or unexported fields }
func (*TokenDecoding) DecodeHS256 ¶
func (c *TokenDecoding) DecodeHS256(key []byte) error
func (*TokenDecoding) SetAuth ¶
func (c *TokenDecoding) SetAuth(rc *RC, auth Auth)
type Val ¶
type Val[T any] struct { // contains filtered or unexported fields }
func (*Val[T]) Get ¶
func (val *Val[T]) Get(o ExpandableObject) T
func (*Val[T]) Set ¶
func (val *Val[T]) Set(o ExpandableObject, v T)
type ViewData ¶
type ViewData struct { View string Title string TitleVisible bool Layout string Data any SemanticPath string StatusCode int Flash *Flash ContentType string *SiteData Route *Route App *App RC any // Content is only populated in layouts and contains the rendered content of the page Content template.HTML // Head is extra HEAD content Head template.HTML // contains filtered or unexported fields }
func (*ViewData) DefaultPathParams ¶
func (vd *ViewData) DefaultPathParams() PathParamsMapStr
Source Files
¶
- app-migration.go
- app.go
- auth.go
- builtin.go
- cache.go
- clock.go
- consts.go
- context.go
- db-changes.go
- db.go
- email.go
- errors.go
- expandables.go
- flash.go
- fs.go
- gracefulshutdown.go
- hooks.go
- http-statics.go
- jobs-ephemeral.go
- jobs.go
- live.go
- logging.go
- mvpmain.go
- panic.go
- ratelimiting.go
- rc.go
- routing-app.go
- routing-builder.go
- routing-context.go
- routing-middlewarenhooks.go
- routing-multidomain.go
- routing-route.go
- routing-rpc.go
- routing-simple.go
- routing-urlgen.go
- routing-util.go
- rpc.go
- serving-errors.go
- serving-forms.go
- serving-response.go
- serving-viewdata.go
- serving-viewhelpers.go
- serving-views.go
- settings-configuration.go
- settings-module.go
- settings.go
- util.go
- valueset.go
Directories
¶
Path | Synopsis |
---|---|
Package director launches a bunch of components and gets them restarted on failure.
|
Package director launches a bunch of components and gets them restarted on failure. |
Package flake manages IDs very similar to snowflake IDs used by Twitter and others.
|
Package flake manages IDs very similar to snowflake IDs used by Twitter and others. |
Package flogger stands for Fire Logger; keep your naughty thoughts to yourself.
|
Package flogger stands for Fire Logger; keep your naughty thoughts to yourself. |
Package fnv implements mixing of various values using 64-bit FNV1a alg.
|
Package fnv implements mixing of various values using 64-bit FNV1a alg. |
Package httpcall takes boilerplate out of typical non-streaming single-roundtrip HTTP API calls.
|
Package httpcall takes boilerplate out of typical non-streaming single-roundtrip HTTP API calls. |
Package httperrors defines an error wrapper that carries extra data for convenient rendering of errors in HTTP responses, esp.
|
Package httperrors defines an error wrapper that carries extra data for convenient rendering of errors in HTTP responses, esp. |
See https://html.spec.whatwg.org/multipage/server-sent-events.html
|
See https://html.spec.whatwg.org/multipage/server-sent-events.html |