Documentation
¶
Index ¶
- Constants
- Variables
- func CheckListenerExists(clientId string, publishers ...publisher.I) bool
- func CheckSubscriptionExists(clientId string, subscriptionId string, publishers ...publisher.I) bool
- func ExposeMiddleware(ctx huma.Context, next func(huma.Context))
- func New(s server.I, name, version, description string, path string, sm *servemux.S)
- func NewHuma(router *servemux.S, name, version, description string) (api huma.API)
- type DeliverChan
- type Delivery
- type Event
- type EventInput
- type EventOutput
- type EventsInput
- type EventsOutput
- type ExportInput
- type ExportOutput
- type Filter
- type H
- type ImportInput
- type ImportOutput
- type ListenInput
- type OK
- type OKs
- type Operations
- func (x *Operations) RegisterEvent(api huma.API)
- func (x *Operations) RegisterEvents(api huma.API)
- func (x *Operations) RegisterExport(api huma.API)
- func (x *Operations) RegisterImport(api huma.API)
- func (x *Operations) RegisterListen(api huma.API)
- func (x *Operations) RegisterSubscribe(api huma.API)
- func (x *Operations) RegisterUnsubscribe(api huma.API)
- type Publisher
- type SubscribeInput
- type UnsubscribeInput
Constants ¶
const Type = "openapi"
Variables ¶
var EventBody = &huma.RequestBody{ Description: "a signed nostr event", Content: map[string]*huma.MediaType{ "application/json": { Schema: &huma.Schema{ Type: huma.TypeObject, Properties: map[string]*huma.Schema{ "id": { Type: huma.TypeString, Description: "SHA256 hash of event in canonical (JSON array with fixed ordering) form, 64 characters hex", }, "pubkey": { Type: huma.TypeString, Description: "BIP-340 Schnorr public key, 64 characters hex", }, "created_at": { Type: huma.TypeInteger, Description: "unix timestamp of time of event creation", }, "kind": { Type: huma.TypeInteger, Description: "kind number of event", }, "tags": { Type: huma.TypeArray, Description: "array of arrays of strings", Items: &huma.Schema{ Type: huma.TypeArray, Items: &huma.Schema{ Type: huma.TypeString, }, }, }, "content": { Type: huma.TypeString, Description: "content of event, escaped using NIP-01 standard escapes and UTF-8 encoding", }, "sig": { Type: huma.TypeString, Description: "BIP-340 Schnorr signature, 128 characters hex", }, }, }, }, }, }
var EventsBody = &huma.RequestBody{ Description: "array of nostr events", Content: map[string]*huma.MediaType{ "application/json": { Schema: &huma.Schema{ Type: huma.TypeObject, Examples: []any{ Filter{ Kinds: []int{0, 1}, Authors: []string{ "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", }, Tag_e: []string{ "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", }, Since: &exampleSince, Until: &exampleUntil, Limit: &exampleLimit, }, Filter{ Ids: []string{ "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", "deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008deadbeefcafe8008", }, }, }, Properties: map[string]*huma.Schema{ "ids": { Type: huma.TypeArray, Description: "list of event IDs to search for (if present, all other fields are excluded)", Items: &huma.Schema{ Type: huma.TypeString, }, }, "kinds": { Type: huma.TypeArray, Description: "list of event kinds to search for", Items: &huma.Schema{ Type: huma.TypeInteger, }, }, "authors": { Type: huma.TypeArray, Description: "list of pubkeys to search for", Items: &huma.Schema{ Type: huma.TypeString, }, }, "^#[a-zA-Z]$": { Type: huma.TypeArray, Description: "list of tag values to search for", Items: &huma.Schema{ Type: huma.TypeString, }, }, "since": { Type: huma.TypeInteger, Description: "earliest (smallest, inclusive) created_at value for events", Minimum: &created_atMinimum, Maximum: &created_atMaximum, }, "until": { Type: huma.TypeInteger, Description: "latest (largest, inclusive) created_at value for events", Minimum: &created_atMinimum, Maximum: &created_atMaximum, }, "limit": { Type: huma.TypeInteger, Description: "maximum number of events to return (newest first, reverse chronological order)", Minimum: &limitMinimum, Maximum: &limitMaximum, }, }, }, }, }, }
var Ok = OKs{ Ok: func( a *Operations, eid eventId.Ider, format string, params ...any, ) (err error) { return nil }, AuthRequired: func( a *Operations, eid eventId.Ider, format string, params ...any, ) (err error) { return huma.Error401Unauthorized( string( reason.AuthRequired.F(format, params...), ), ) }, PoW: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error406NotAcceptable( string( reason.PoW.F(format, params...), ), ) }, Duplicate: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error422UnprocessableEntity( string( reason.Duplicate.F(format, params...), ), ) }, Blocked: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error406NotAcceptable( string( reason.Blocked.F(format, params...), ), ) }, RateLimited: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error400BadRequest( string( reason.RateLimited.F(format, params...), ), ) }, Invalid: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error422UnprocessableEntity( string( reason.Invalid.F(format, params...), ), ) }, Error: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error500InternalServerError( string( reason.Error.F(format, params...), ), ) }, Unsupported: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error400BadRequest( string( reason.Unsupported.F(format, params...), ), ) }, Restricted: func( a *Operations, _ eventId.Ider, format string, params ...any, ) (err error) { return huma.Error403Forbidden( string( reason.Restricted.F(format, params...), ), ) }, }
Ok provides a collection of handler functions for managing different types of operational outcomes, each corresponding to specific error or status conditions such as authentication requirements, rate limiting, and invalid inputs.
Functions ¶
func CheckListenerExists ¶ added in v0.3.0
CheckListenerExists is a package-level function that checks if a listener exists. This function is used by the Subscribe and Unsubscribe APIs to check if a client ID exists.
func CheckSubscriptionExists ¶ added in v0.3.0
func CheckSubscriptionExists( clientId string, subscriptionId string, publishers ...publisher.I, ) bool
CheckSubscriptionExists is a package-level function that checks if a subscription exists for a specific listener. This function is used by the Unsubscribe API to check if a subscription ID exists before attempting to unsubscribe.
func ExposeMiddleware ¶
ExposeMiddleware adds the http.Request and http.ResponseWriter to the context for the Operations handler.
Types ¶
type DeliverChan ¶ added in v0.3.0
type DeliverChan chan *Delivery
type EventInput ¶ added in v0.2.14
type EventInput struct {
Auth string `header:"Authorization" doc:"nostr nip-98 (and expiring variant)" required:"false"`
Accept string `header:"Accept" default:"application/nostr+json"`
Body *event.J `doc:"event JSON"`
}
EventInput is the parameters for the Event HTTP API method.
type EventOutput ¶ added in v0.2.14
type EventOutput struct{}
EventOutput is the return parameters for the HTTP API Event method.
type EventsInput ¶ added in v0.2.20
type EventsOutput ¶ added in v0.2.20
type ExportInput ¶ added in v0.2.11
type ExportInput struct {
Auth string `header:"Authorization" doc:"nostr nip-98 (and expiring variant)" required:"true"`
}
ExportInput is the parameters for the HTTP API Export method.
type ExportOutput ¶ added in v0.2.11
type ExportOutput struct{ RawBody []byte }
ExportOutput is the return value of Export. It usually will be line structured JSON.
type Filter ¶ added in v0.2.20
type Filter struct {
Ids []string `json:"ids,omitempty"`
Kinds []int `json:"kinds,omitempty"`
Authors []string `json:"authors,omitempty"`
Tag_a []string `json:"#a,omitempty"`
Tag_b []string `json:"#b,omitempty"`
Tag_c []string `json:"#c,omitempty"`
Tag_d []string `json:"#d,omitempty"`
Tag_e []string `json:"#e,omitempty"`
Tag_f []string `json:"#f,omitempty"`
Tag_g []string `json:"#g,omitempty"`
Tag_h []string `json:"#h,omitempty"`
Tag_i []string `json:"#i,omitempty"`
Tag_j []string `json:"#j,omitempty"`
Tag_k []string `json:"#k,omitempty"`
Tag_l []string `json:"#l,omitempty"`
Tag_m []string `json:"#m,omitempty"`
Tag_n []string `json:"#n,omitempty"`
Tag_o []string `json:"#o,omitempty"`
Tag_p []string `json:"#p,omitempty"`
Tag_q []string `json:"#q,omitempty"`
Tag_r []string `json:"#r,omitempty"`
Tag_s []string `json:"#s,omitempty"`
Tag_t []string `json:"#t,omitempty"`
Tag_u []string `json:"#u,omitempty"`
Tag_v []string `json:"#v,omitempty"`
Tag_w []string `json:"#w,omitempty"`
Tag_x []string `json:"#x,omitempty"`
Tag_y []string `json:"#y,omitempty"`
Tag_z []string `json:"#z,omitempty"`
Tag_A []string `json:"#A,omitempty"`
Tag_B []string `json:"#B,omitempty"`
Tag_C []string `json:"#C,omitempty"`
Tag_D []string `json:"#D,omitempty"`
Tag_E []string `json:"#E,omitempty"`
Tag_F []string `json:"#F,omitempty"`
Tag_G []string `json:"#G,omitempty"`
Tag_H []string `json:"#H,omitempty"`
Tag_I []string `json:"#I,omitempty"`
Tag_J []string `json:"#J,omitempty"`
Tag_K []string `json:"#K,omitempty"`
Tag_L []string `json:"#L,omitempty"`
Tag_M []string `json:"#M,omitempty"`
Tag_N []string `json:"#N,omitempty"`
Tag_O []string `json:"#O,omitempty"`
Tag_P []string `json:"#P,omitempty"`
Tag_Q []string `json:"#Q,omitempty"`
Tag_R []string `json:"#R,omitempty"`
Tag_S []string `json:"#S,omitempty"`
Tag_T []string `json:"#T,omitempty"`
Tag_U []string `json:"#U,omitempty"`
Tag_V []string `json:"#V,omitempty"`
Tag_W []string `json:"#W,omitempty"`
Tag_X []string `json:"#X,omitempty"`
Tag_Y []string `json:"#Y,omitempty"`
Tag_Z []string `json:"#Z,omitempty"`
Since *int64 `json:"since,omitempty"`
Until *int64 `json:"until,omitempty"`
Search *string `json:"search,omitempty"`
Limit *int `json:"limit,omitempty"`
}
type H ¶ added in v0.3.0
type H struct {
sync.Mutex
// If Cancel is true, this is a close command (must be done when a listener
// connection is closed).
Cancel bool
// New is a flag that signifies a newly created client_id
New bool
// Id is the identifier for an HTTP subscription listener channel
Id string
// FilterMap is the collection of filters associated with a listener.
FilterMap map[string]*filter.F
// Receiver is the channel for receiving events
Receiver DeliverChan
// Pubkey is the authenticated public key for this listener
Pubkey []byte
}
type ImportInput ¶ added in v0.2.12
type ImportInput struct {
Auth string `header:"Authorization" doc:"nostr nip-98 (and expiring variant) token for authentication" required:"true"`
Body string `doc:"events in line structured JSON (JSONL)"`
}
ImportInput is the parameters of an import operation, authentication and the stream of line structured JSON events.
type ImportOutput ¶ added in v0.2.12
type ImportOutput struct{}
ImportOutput is nothing, basically; a 204 or 200 status is expected.
type ListenInput ¶ added in v0.3.0
type OK ¶ added in v0.2.14
OK represents a function that processes events or operations, using provided parameters to generate formatted messages and return errors if any issues occur during processing.
type OKs ¶ added in v0.2.14
type OKs struct {
Ok OK
AuthRequired OK
PoW OK
Duplicate OK
Blocked OK
RateLimited OK
Invalid OK
Error OK
Unsupported OK
Restricted OK
}
OKs provides a collection of handler functions for managing different types of operational outcomes, each corresponding to specific error or status conditions such as authentication requirements, rate limiting, and invalid inputs.
type Operations ¶
func (*Operations) RegisterEvent ¶ added in v0.2.14
func (x *Operations) RegisterEvent(api huma.API)
RegisterEvent is the implementation of the HTTP API Event method.
func (*Operations) RegisterEvents ¶ added in v0.2.20
func (x *Operations) RegisterEvents(api huma.API)
RegisterEvents is the implementation of the HTTP API Events method.
This method returns the results of a single filter query, filtered by privilege.
func (*Operations) RegisterExport ¶ added in v0.2.11
func (x *Operations) RegisterExport(api huma.API)
RegisterExport implements the Export HTTP API method.
func (*Operations) RegisterImport ¶ added in v0.2.12
func (x *Operations) RegisterImport(api huma.API)
RegisterImport is the implementation of the Import operation.
func (*Operations) RegisterListen ¶ added in v0.3.0
func (x *Operations) RegisterListen(api huma.API)
func (*Operations) RegisterSubscribe ¶ added in v0.3.0
func (x *Operations) RegisterSubscribe(api huma.API)
func (*Operations) RegisterUnsubscribe ¶ added in v0.3.0
func (x *Operations) RegisterUnsubscribe(api huma.API)
type Publisher ¶ added in v0.3.0
type Publisher struct {
sync.Mutex
// ListenMap maps listener IDs to listener objects
ListenMap map[string]*H
// Server is an interface to the server
Server server.I
}
func NewPublisher ¶ added in v0.3.0
func (*Publisher) Deliver ¶ added in v0.3.0
Deliver processes and distributes an event to all matching subscribers based on their filter configurations.
Parameters ¶
- ev (*event.E): The event to be delivered to subscribed clients.
Expected behaviour ¶
Delivers the event to all subscribers whose filters match the event. It applies authentication checks if required by the server, and skips delivery for unauthenticated users when events are privileged.
func (*Publisher) ListenerExists ¶ added in v0.3.0
ListenerExists checks if a listener with the given ID exists.
func (*Publisher) Receive ¶ added in v0.3.0
Receive handles incoming messages to manage HTTP listener subscriptions and associated filters.
Parameters ¶
- msg (typer.T): The incoming message to process; expected to be of type *H to trigger subscription management actions.
Expected behaviour ¶
- Checks if the message is of type *H.
- If Cancel is true, removes a subscriber by ID or the entire listener.
- Otherwise, adds the subscription to the map under a mutex lock.
- Logs actions related to subscription creation or removal.
func (*Publisher) SubscriptionExists ¶ added in v0.3.0
SubscriptionExists checks if a subscription with the given ID exists for a specific listener.
type SubscribeInput ¶ added in v0.3.0
type SubscribeInput struct {
Auth string `header:"Authorization" doc:"nostr nip-98 (and expiring variant)" required:"false"`
Accept string `header:"Accept" default:"application/nostr+json"`
ClientId string `path:"client_id" doc:"Client identifier code associated with subscription channel created with /listen"`
Id string `path:"id" doc:"Identifier of the subscription associated with the filter"`
Body *Filter `doc:"filter JSON (standard NIP-01 filter syntax)"`
}