proxy

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MergeRouteManifest

func MergeRouteManifest(base, overlay *RouteManifest)

MergeRouteManifest copies non-empty string fields and bool fields from overlay onto base (mutates base). Used when applying tenant:{ref}:manifest over lower-priority layers.

func New

func New(target *url.URL, opts ProxyOpts) http.Handler

New returns an http.Handler that reverse-proxies requests to target. The handler forwards X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, and RFC 7239 Forwarded (one appended hop), strips CORS headers from the upstream response (supatype-server is the sole source of CORS truth), and adds any HeaderOverrides before forwarding.

func Watch

func Watch(path string, fn func(*RouteManifest)) error

Watch starts a goroutine that calls fn whenever the manifest file at path changes. The goroutine exits when ctx is done.

func WebSocketProxy

func WebSocketProxy(target *url.URL, fallback http.Handler) http.Handler

WebSocketProxy returns an http.Handler that proxies WebSocket connections to target. It detects "Connection: Upgrade" + "Upgrade: websocket", hijacks the connection, dials target directly, and splices the two TCP connections bidirectionally. Non-WebSocket requests are passed to fallback.

Types

type HookConfig added in v1.4.0

type HookConfig struct {
	// Function is the function name, as discovered by the worker (its directory name).
	Function string `json:"function"`

	// TimeoutMs abandons the hook after this long. The CLI fills a default well below the
	// edge-function ceiling, so a hung hook fails fast instead of holding an invocation slot.
	TimeoutMs int `json:"timeout,omitempty"`

	// OnUnavailable is what a hook that does not *answer* means — a timeout, a connection failure,
	// a 5xx, an unparseable body. "reject" fails the write, "log" allows it.
	//
	// Deliberately not consulted for a 4xx: that is the hook working correctly and saying no, and it
	// reaches the caller as the status the hook chose. Collapsing the two would mean either a broken
	// hook silently passing writes it was meant to check, or a considered rejection reading as an
	// outage.
	OnUnavailable string `json:"onUnavailable,omitempty"`
}

HookConfig is one hook: the edge function to call and how to treat its silence.

type ProxyOpts

type ProxyOpts struct {
	// StripPrefix removes this prefix from the request path before forwarding.
	StripPrefix string

	// HeaderOverrides sets (or replaces) these headers on every forwarded request.
	HeaderOverrides map[string]string

	// HeaderFunc, when set, is called per-request and its return value is merged
	// with HeaderOverrides (HeaderFunc takes precedence on key conflicts).
	HeaderFunc func(*http.Request) map[string]string

	// RequestTimeout caps the upstream round-trip duration.
	RequestTimeout time.Duration
}

ProxyOpts configures the behaviour of a reverse proxy handler.

type RouteManifest

type RouteManifest struct {
	// Schema is the Postgres schema name (default: "public").
	Schema string `json:"schema"`

	// PostgRESTURL overrides SUPATYPE_POSTGREST_URL when set.
	PostgRESTURL string `json:"postgrest_url,omitempty"`

	// GraphQLURL overrides SUPATYPE_GRAPHQL_URL when set.
	GraphQLURL string `json:"graphql_url,omitempty"`

	// StorageURL overrides SUPATYPE_STORAGE_URL when set.
	StorageURL string `json:"storage_url,omitempty"`

	// AppMode overrides SUPATYPE_APP_MODE when set ("none"|"static"|"proxy").
	AppMode string `json:"app_mode,omitempty"`

	// AppStaticDir overrides SUPATYPE_APP_STATIC_DIR when set.
	AppStaticDir string `json:"app_static_dir,omitempty"`

	// AppUpstream overrides SUPATYPE_APP_UPSTREAM when set.
	AppUpstream string `json:"app_upstream,omitempty"`

	// ViteDevURL overrides SUPATYPE_VITE_DEV_URL when set (dev HMR at /_vite/*).
	ViteDevURL string `json:"vite_dev_url,omitempty"`

	// RealtimeEnabled gates /realtime/v1 (tier / feature flag).
	RealtimeEnabled bool `json:"realtime_enabled"`

	// RealtimeURL overrides SUPATYPE_REALTIME_URL when set (internal realtime service base URL).
	RealtimeURL string `json:"realtime_url,omitempty"`

	// FunctionsEnabled indicates the Deno functions subsystem should start.
	FunctionsEnabled bool `json:"functions_enabled"`

	// FunctionsWorkerURL is the per-project worker base URL (Pro+ / self-host).
	FunctionsWorkerURL string `json:"functions_worker_url,omitempty"`

	// FunctionWorkerURLs maps function name → worker base URL (free-tier per-function pool).
	FunctionWorkerURLs map[string]string `json:"function_worker_urls,omitempty"`

	// CorsAllowedOrigins lists allowed browser Origin values (exact match).
	// Merged from Valkey tenant config / manifest in managed mode; may be
	// combined with SUPATYPE_CORS_ALLOW_ORIGINS on the server.
	CorsAllowedOrigins []string `json:"cors_allowed_origins,omitempty"`

	// StaticCacheHTML overrides Cache-Control for HTML responses and SPA fallback (default no-cache).
	StaticCacheHTML string `json:"static_cache_html,omitempty"`

	// StaticCacheHashedAssets overrides Cache-Control for bundled/hashed asset paths (default immutable long cache).
	StaticCacheHashedAssets string `json:"static_cache_hashed_assets,omitempty"`

	// StaticCachePrefixes maps URL path prefix → Cache-Control (longest matching prefix wins).
	StaticCachePrefixes map[string]string `json:"static_cache_prefixes,omitempty"`

	// Hooks maps table name → lifecycle hooks, written by `supatype push`.
	//
	// Keyed by table because that is what a REST path carries; the model name never reaches the
	// wire. Absent for a project that declares none, which is the common case.
	Hooks map[string]TableHooks `json:"hooks,omitempty"`
}

RouteManifest describes the active upstream services for this project. It is written by `supatype push` (engine generate --manifest-out) and read by supatype-server on startup and on SIGHUP / file change.

func CloneRouteManifest

func CloneRouteManifest(m *RouteManifest) *RouteManifest

CloneRouteManifest returns a copy with schema default applied.

func Load

func Load(path string) (*RouteManifest, error)

Load reads and parses the manifest at path. Returns an empty manifest (not an error) if the file does not exist yet — this is normal on first run before `supatype push` has been called.

func ParseRouteManifestJSON

func ParseRouteManifestJSON(data []byte) (*RouteManifest, error)

ParseRouteManifestJSON unmarshals JSON bytes into RouteManifest (same shape as manifest.json).

type TableHooks added in v1.4.0

type TableHooks map[string]HookConfig

TableHooks is one table's lifecycle hooks, keyed by event ("beforeChange", "afterChange", "beforeDelete", "afterDelete").

Jump to

Keyboard shortcuts

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