From eebf981b319616ab2f30630ad40c62c98969860e Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Wed, 1 Jul 2026 13:09:13 +0200 Subject: [PATCH 1/4] Add new Register method --- pkg/httprouter/router.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pkg/httprouter/router.go b/pkg/httprouter/router.go index c0b5340..1d7c67c 100644 --- a/pkg/httprouter/router.go +++ b/pkg/httprouter/router.go @@ -213,6 +213,23 @@ func (r *Router) RegisterFS(path string, fs fs.FS, middleware bool, spec *openap return r.safeHandle(prefix, handler) } +// Register registers a [PathItem] handler at path. If path is relative +// the router prefix is prepended. Any security schemes referenced by the +// path item's OpenAPI operations must already be registered on the router; +// matching handlers are wrapped with those security schemes before the +// router's middleware chain is applied. +func (r *Router) Register(path string, params *jsonschema.Schema, fn func(pathitem httprequest.PathItem) error) error { + // Resolve the path with the router prefix + path = r.resolvePath(path) + + // Populate the path item by calling the provided function + pathitem := httprequest.NewPathItem("SUMMARY", "DESCRIPTION") + if err := fn(pathitem); err != nil { + return err + } + return r.RegisterPath(path, params, pathitem) +} + // RegisterPath registers a [PathItem] handler at path. If path is relative // the router prefix is prepended. Any security schemes referenced by the // path item's OpenAPI operations must already be registered on the router; From 5f590ce85bba078434755dc87546416993b59bd8 Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Wed, 1 Jul 2026 18:23:32 +0200 Subject: [PATCH 2/4] Updates --- pkg/httprequest/path.go | 254 +++++++++++++++++++++++++---- pkg/httprouter/router.go | 10 +- pkg/openapi/httphandler/README.md | 19 +++ pkg/openapi/httphandler/handler.go | 108 ++++++------ 4 files changed, 301 insertions(+), 90 deletions(-) create mode 100644 pkg/openapi/httphandler/README.md diff --git a/pkg/httprequest/path.go b/pkg/httprequest/path.go index 7be2b1e..1b00629 100644 --- a/pkg/httprequest/path.go +++ b/pkg/httprequest/path.go @@ -2,6 +2,8 @@ package httprequest import ( "net/http" + "slices" + "strconv" "strings" // Packages @@ -16,6 +18,34 @@ import ( // INTERFACES type PathItem interface { + // Add one or more tags to the path item. + // Tags are used to group operations in the OpenAPI document. + Tag(...string) PathItem + + // Get registers a GET handler with the given summary and operation options. + Get(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Put registers a PUT handler with the given summary and operation options. + Put(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Post registers a POST handler with the given summary and operation options. + Post(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Delete registers a DELETE handler with the given summary and operation options. + Delete(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Patch registers a PATCH handler with the given summary and operation options. + Patch(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Options registers an OPTIONS handler with the given summary and operation options. + Options(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Head registers a HEAD handler with the given summary and operation options. + Head(handler http.HandlerFunc, fn func(PathOperation)) PathItem + + // Trace registers a TRACE handler with the given summary and operation options. + Trace(handler http.HandlerFunc, fn func(PathOperation)) PathItem + // Handler returns the http.HandlerFunc that handles the PathItem Handler() http.HandlerFunc @@ -28,6 +58,35 @@ type PathItem interface { WrapHandler(method string, fn func(http.HandlerFunc) http.HandlerFunc) } +type PathOperation interface { + // Add one or more tags to the operation. + Tags(...string) PathOperation + + // Set the summary for the operation. + Summary(string) PathOperation + + // Set the description for the operation. + Description(string) PathOperation + + // Set the query parameters for the operation from a JSON schema. + Query(*jsonschema.Schema) PathOperation + + // Mark the operation as deprecated. + Deprecated() PathOperation + + // Add a JSON response for the operation with the given status code and schema. + // An optional description can be provided; if not, the default HTTP status text will be used. + JSONResponse(status int, schema *jsonschema.Schema, description ...string) PathOperation + + // Add an error response for the operation with the given status code. + // An optional description can be provided; if not, the default HTTP status text will be used. + ErrorResponse(status int, description ...string) PathOperation + + // Return a response for the operation with the given status code and content type. + // An optional description can be provided; if not, the default HTTP status text will be used. + Response(status int, contentType string, description ...string) PathOperation +} + /////////////////////////////////////////////////////////////////////////////// // TYPES @@ -37,6 +96,10 @@ type pathitem struct { handlers map[string]http.HandlerFunc } +type pathoperation struct { + spec *openapi.Operation +} + var _ PathItem = (*pathitem)(nil) /////////////////////////////////////////////////////////////////////////////// @@ -58,6 +121,96 @@ func NewPathItem(summary, description string, tags ...string) *pathitem { return self } +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS - PATH ITEM + +// Add one or more tags to the path item. +// Tags are used to group operations in the OpenAPI document. +func (p *pathitem) Tag(tags ...string) PathItem { + p.tags = append(p.tags, tags...) + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Get(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodGet] = handler + p.spec.Get = types.Ptr(openapi_op.Operation(http.MethodGet, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Get}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Put(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodPut] = handler + p.spec.Put = types.Ptr(openapi_op.Operation(http.MethodPut, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Put}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Post(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodPost] = handler + p.spec.Post = types.Ptr(openapi_op.Operation(http.MethodPost, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Post}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Delete(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodDelete] = handler + p.spec.Delete = types.Ptr(openapi_op.Operation(http.MethodDelete, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Delete}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Patch(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodPatch] = handler + p.spec.Patch = types.Ptr(openapi_op.Operation(http.MethodPatch, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Patch}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Options(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodOptions] = handler + p.spec.Options = types.Ptr(openapi_op.Operation(http.MethodOptions, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Options}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Head(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodHead] = handler + p.spec.Head = types.Ptr(openapi_op.Operation(http.MethodHead, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Head}) + } + return p +} + +// Return a new PathOperation for the path item. +func (p *pathitem) Trace(handler http.HandlerFunc, fn func(PathOperation)) PathItem { + p.handlers[http.MethodTrace] = handler + p.spec.Trace = types.Ptr(openapi_op.Operation(http.MethodTrace, openapi_op.WithTags(p.tags...))) + if fn != nil { + fn(&pathoperation{spec: p.spec.Trace}) + } + return p +} + /////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS @@ -88,59 +241,73 @@ func (p *pathitem) WrapHandler(method string, fn func(http.HandlerFunc) http.Han } } -// Get registers a GET handler with the given summary and operation options. -func (p *pathitem) Get(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodGet] = handler - p.spec.Get = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS - PATH OPERATION + +func (p *pathoperation) Tags(tags ...string) PathOperation { + p.spec.Tags = append(p.spec.Tags, tags...) return p } -// Put registers a PUT handler with the given summary and operation options. -func (p *pathitem) Put(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodPut] = handler - p.spec.Put = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) Summary(summary string) PathOperation { + p.spec.Summary = summary return p } -// Post registers a POST handler with the given summary and operation options. -func (p *pathitem) Post(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodPost] = handler - p.spec.Post = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) Description(description string) PathOperation { + p.spec.Description = description return p } -// Delete registers a DELETE handler with the given summary and operation options. -func (p *pathitem) Delete(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodDelete] = handler - p.spec.Delete = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) Query(q *jsonschema.Schema) PathOperation { + p.spec.Parameters = append(p.spec.Parameters, parametersFromQuery(q)...) return p } -// Patch registers a PATCH handler with the given summary and operation options. -func (p *pathitem) Patch(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodPatch] = handler - p.spec.Patch = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) Deprecated() PathOperation { + p.spec.Deprecated = true return p } -// Options registers an OPTIONS handler with the given summary and operation options. -func (p *pathitem) Options(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodOptions] = handler - p.spec.Options = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) JSONResponse(status int, schema *jsonschema.Schema, description ...string) PathOperation { + if p.spec.Responses == nil { + p.spec.Responses = make(map[string]openapi.Response) + } + statusNum := strconv.FormatInt(int64(status), 10) + descriptionText := strings.Join(description, " ") + if descriptionText == "" { + descriptionText = http.StatusText(status) + } + p.spec.Responses[statusNum] = openapi.Response{ + Description: descriptionText, + Content: map[string]openapi.MediaType{ + types.ContentTypeJSON: { + Schema: schema, + }, + }, + } return p } -// Head registers a HEAD handler with the given summary and operation options. -func (p *pathitem) Head(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodHead] = handler - p.spec.Head = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) - return p +func (p *pathoperation) ErrorResponse(status int, description ...string) PathOperation { + return p.JSONResponse(status, jsonschema.MustFor[httpresponse.ErrResponse](), description...) } -// Trace registers a TRACE handler with the given summary and operation options. -func (p *pathitem) Trace(handler http.HandlerFunc, summary string, opts ...openapi_op.OperationOpt) *pathitem { - p.handlers[http.MethodTrace] = handler - p.spec.Trace = types.Ptr(openapi_op.Operation(summary, append([]openapi_op.OperationOpt{openapi_op.WithTags(p.tags...)}, opts...)...)) +func (p *pathoperation) Response(status int, contentType string, description ...string) PathOperation { + if p.spec.Responses == nil { + p.spec.Responses = make(map[string]openapi.Response) + } + statusNum := strconv.FormatInt(int64(status), 10) + descriptionText := strings.Join(description, " ") + if descriptionText == "" { + descriptionText = http.StatusText(status) + } + p.spec.Responses[statusNum] = openapi.Response{ + Description: descriptionText, + Content: map[string]openapi.MediaType{ + contentType: {}, + }, + } return p } @@ -189,3 +356,24 @@ func parametersFromPath(path string, schema *jsonschema.Schema) []openapi.Parame return params } + +func parametersFromQuery(q *jsonschema.Schema) []openapi.Parameter { + if q == nil { + return nil + } + names := make([]string, 0, len(q.Properties)) + for name := range q.Properties { + names = append(names, name) + } + slices.Sort(names) + params := make([]openapi.Parameter, 0, len(names)) + for _, name := range names { + params = append(params, openapi.Parameter{ + Name: name, + In: openapi.ParameterInQuery, + Required: slices.Contains(q.Required, name), + Schema: q.Property(name), + }) + } + return params +} diff --git a/pkg/httprouter/router.go b/pkg/httprouter/router.go index 1d7c67c..30b38b8 100644 --- a/pkg/httprouter/router.go +++ b/pkg/httprouter/router.go @@ -218,15 +218,15 @@ func (r *Router) RegisterFS(path string, fs fs.FS, middleware bool, spec *openap // path item's OpenAPI operations must already be registered on the router; // matching handlers are wrapped with those security schemes before the // router's middleware chain is applied. -func (r *Router) Register(path string, params *jsonschema.Schema, fn func(pathitem httprequest.PathItem) error) error { +func (r *Router) Register(path string, params *jsonschema.Schema, fn func(pathitem httprequest.PathItem)) error { // Resolve the path with the router prefix path = r.resolvePath(path) + pathitem := httprequest.NewPathItem("SUMMARY", "DESCRIPTION") // Populate the path item by calling the provided function - pathitem := httprequest.NewPathItem("SUMMARY", "DESCRIPTION") - if err := fn(pathitem); err != nil { - return err - } + fn(pathitem) + + // Register the path item return r.RegisterPath(path, params, pathitem) } diff --git a/pkg/openapi/httphandler/README.md b/pkg/openapi/httphandler/README.md new file mode 100644 index 0000000..273980f --- /dev/null +++ b/pkg/openapi/httphandler/README.md @@ -0,0 +1,19 @@ +# OpenAPI Operations + +Downloadable OpenAPI specifications are available at the following paths relative to the router's prefix: + +* `openapi.json` — JSON (application/json) +* `openapi.yaml` — YAML (application/yaml) +* `openapi.html` — HTML (text/html) + +## GET /openapi.json + +Return OpenAPI specification in JSON format + +## GET /openapi.yaml + +Return OpenAPI specification in YAML format + +## GET /openapi.html + +Return OpenAPI specification in HTML format, which can be viewed in a web browser diff --git a/pkg/openapi/httphandler/handler.go b/pkg/openapi/httphandler/handler.go index c894958..db8f934 100644 --- a/pkg/openapi/httphandler/handler.go +++ b/pkg/openapi/httphandler/handler.go @@ -1,7 +1,8 @@ -// Package httphandler provides HTTP handler functions for an [httprouter.Router]. package httphandler import ( + _ "embed" + "errors" "io" "net/http" @@ -9,73 +10,76 @@ import ( httprequest "github.com/mutablelogic/go-server/pkg/httprequest" httpresponse "github.com/mutablelogic/go-server/pkg/httpresponse" httprouter "github.com/mutablelogic/go-server/pkg/httprouter" + jsonschema "github.com/mutablelogic/go-server/pkg/jsonschema" + openapi "github.com/mutablelogic/go-server/pkg/openapi" + openapischema "github.com/mutablelogic/go-server/pkg/openapi/schema" static "github.com/mutablelogic/go-server/pkg/openapi/static" types "github.com/mutablelogic/go-server/pkg/types" yaml "gopkg.in/yaml.v3" ) +/////////////////////////////////////////////////////////////////////////////// +// TYPES + const ( pathJSON = "openapi.json" pathYAML = "openapi.yaml" pathHTML = "openapi.html" ) +//go:embed README.md +var readme []byte + +/////////////////////////////////////////////////////////////////////////////// +// LIFECYCLE + // RegisterHandler registers GET handlers that serve the router's OpenAPI // specification at two paths relative to the router's prefix: // - openapi.json — JSON (application/json) // - openapi.yaml — YAML (application/yaml) // - openapi.html — HTML documentation (text/html) func RegisterHandler(router *httprouter.Router) error { - if err := router.RegisterPath(pathJSON, nil, - httprequest.NewPathItem("OpenAPI JSON", "Serve the OpenAPI specification as JSON", "OpenAPI").Get(jsonHandler(router), "Get OpenAPI JSON"), - ); err != nil { - return err - } - if err := router.RegisterPath(pathYAML, nil, - httprequest.NewPathItem("OpenAPI YAML", "Serve the OpenAPI specification as YAML", "OpenAPI").Get(yamlHandler(router), "Get OpenAPI YAML"), - ); err != nil { - return err - } - return router.RegisterPath(pathHTML, nil, - httprequest.NewPathItem("OpenAPI HTML", "Serve the OpenAPI documentation UI", "OpenAPI").Get(htmlHandler(), "Get OpenAPI HTML"), + var documentation = openapi.ParseMarkdown(readme) + router.Spec().AddTag("OpenAPI", documentation.Section(1, "OpenAPI Operations").Body) + return errors.Join( + router.Register(pathJSON, nil, func(path httprequest.PathItem) { + path.Tag("OpenAPI") + path.Get(func(w http.ResponseWriter, r *http.Request) { + httpresponse.JSON(w, http.StatusOK, httprequest.Indent(r), router.Spec()) + }, func(op httprequest.PathOperation) { + op.Summary("Return JSON Specification") + op.Description(documentation.Section(2, "GET /openapi.json").Body) + op.JSONResponse(http.StatusOK, jsonschema.MustFor[openapischema.Spec]()) + }) + }), + router.Register(pathYAML, nil, func(path httprequest.PathItem) { + path.Tag("OpenAPI") + path.Get(func(w http.ResponseWriter, r *http.Request) { + data, err := yaml.Marshal(router.Spec()) + if err != nil { + _ = httpresponse.Error(w, err) + return + } + _ = httpresponse.Write(w, http.StatusOK, types.ContentTypeYAML, func(out io.Writer) (int, error) { + return out.Write(data) + }) + }, func(op httprequest.PathOperation) { + op.Summary("Return YAML Specification") + op.Description(documentation.Section(2, "GET /openapi.yaml").Body) + op.Response(http.StatusOK, types.ContentTypeYAML, "OpenAPI specification in YAML format") + }) + }), + router.Register(pathHTML, nil, func(path httprequest.PathItem) { + path.Tag("OpenAPI") + path.Get(func(w http.ResponseWriter, r *http.Request) { + _ = httpresponse.Write(w, http.StatusOK, types.ContentTypeHTML+"; charset=utf-8", func(out io.Writer) (int, error) { + return out.Write(static.OpenAPIHTML) + }) + }, func(op httprequest.PathOperation) { + op.Summary("Return HTML Documentation") + op.Description(documentation.Section(2, "GET /openapi.html").Body) + op.Response(http.StatusOK, types.ContentTypeHTML, "OpenAPI specification in HTML format") + }) + }), ) } - -func jsonHandler(router *httprouter.Router) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - _ = httpresponse.Error(w, httpresponse.Err(http.StatusMethodNotAllowed), r.Method) - return - } - _ = httpresponse.JSON(w, http.StatusOK, httprequest.Indent(r), router.Spec()) - } -} - -func yamlHandler(router *httprouter.Router) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - _ = httpresponse.Error(w, httpresponse.Err(http.StatusMethodNotAllowed), r.Method) - return - } - data, err := yaml.Marshal(router.Spec()) - if err != nil { - _ = httpresponse.Error(w, err) - return - } - _ = httpresponse.Write(w, http.StatusOK, types.ContentTypeYAML, func(out io.Writer) (int, error) { - return out.Write(data) - }) - } -} - -func htmlHandler() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - _ = httpresponse.Error(w, httpresponse.Err(http.StatusMethodNotAllowed), r.Method) - return - } - _ = httpresponse.Write(w, http.StatusOK, types.ContentTypeHTML+"; charset=utf-8", func(out io.Writer) (int, error) { - return out.Write(static.OpenAPIHTML) - }) - } -} From 44c228e9e5315c5a052d92050a104818a8db1e1c Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Sat, 4 Jul 2026 09:28:28 +0200 Subject: [PATCH 3/4] Added RequestBody --- pkg/httprequest/path.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pkg/httprequest/path.go b/pkg/httprequest/path.go index 1b00629..7cc1754 100644 --- a/pkg/httprequest/path.go +++ b/pkg/httprequest/path.go @@ -74,6 +74,10 @@ type PathOperation interface { // Mark the operation as deprecated. Deprecated() PathOperation + // Add a request body for the operation with the given content type and schema. + // An optional description can be provided. If no content type is provided, "application/json" is used. + RequestBody(schema *jsonschema.Schema, contentType ...string) PathOperation + // Add a JSON response for the operation with the given status code and schema. // An optional description can be provided; if not, the default HTTP status text will be used. JSONResponse(status int, schema *jsonschema.Schema, description ...string) PathOperation @@ -311,6 +315,21 @@ func (p *pathoperation) Response(status int, contentType string, description ... return p } +func (p *pathoperation) RequestBody(schema *jsonschema.Schema, contentType ...string) PathOperation { + ct := types.ContentTypeJSON + if len(contentType) > 0 { + ct = contentType[0] + } + p.spec.RequestBody = &openapi.RequestBody{ + Content: map[string]openapi.MediaType{ + ct: { + Schema: schema, + }, + }, + } + return p +} + /////////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS From 6dcef2ab903a62ba1ca0e4844d0d9767eb41d2cf Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Sun, 5 Jul 2026 10:36:37 +0200 Subject: [PATCH 4/4] Upgrades --- go.mod | 58 +++++++++++++-------------- go.sum | 122 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 91 insertions(+), 89 deletions(-) diff --git a/go.mod b/go.mod index af3918c..68fa7b5 100644 --- a/go.mod +++ b/go.mod @@ -5,30 +5,30 @@ go 1.25.0 require ( github.com/alecthomas/kong v1.15.0 github.com/charmbracelet/lipgloss v1.1.0 - github.com/google/jsonschema-go v0.4.2 + github.com/google/jsonschema-go v0.4.3 github.com/google/uuid v1.6.0 - github.com/mutablelogic/go-client v1.4.9 + github.com/mutablelogic/go-client v1.4.10 github.com/mutablelogic/go-tokenizer v0.0.3 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 - go.opentelemetry.io/otel v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 - go.opentelemetry.io/otel/log v0.19.0 - go.opentelemetry.io/otel/metric v1.43.0 - go.opentelemetry.io/otel/sdk v1.43.0 - go.opentelemetry.io/otel/sdk/log v0.19.0 - go.opentelemetry.io/otel/sdk/metric v1.43.0 - go.opentelemetry.io/otel/trace v1.43.0 - golang.org/x/sync v0.20.0 - golang.org/x/term v0.42.0 + go.opentelemetry.io/contrib/bridges/otelslog v0.19.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 + go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.20.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 + go.opentelemetry.io/otel/log v0.20.0 + go.opentelemetry.io/otel/metric v1.44.0 + go.opentelemetry.io/otel/sdk v1.44.0 + go.opentelemetry.io/otel/sdk/log v0.20.0 + go.opentelemetry.io/otel/sdk/metric v1.44.0 + go.opentelemetry.io/otel/trace v1.44.0 + golang.org/x/sync v0.21.0 + golang.org/x/term v0.44.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -43,24 +43,24 @@ require ( github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/lucasb-eyer/go-colorful v1.4.0 // indirect - github.com/mattn/go-isatty v0.0.21 // indirect - github.com/mattn/go-runewidth v0.0.23 // indirect + github.com/mattn/go-isatty v0.0.22 // indirect + github.com/mattn/go-runewidth v0.0.24 // indirect github.com/muesli/termenv v0.16.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect - golang.org/x/net v0.53.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/text v0.36.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect - google.golang.org/grpc v1.80.0 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/text v0.38.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7 // indirect + google.golang.org/grpc v1.82.0 // indirect google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/go.sum b/go.sum index 825d5da..2e491f3 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJ github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= +github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -41,8 +41,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= -github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0= +github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= @@ -55,14 +55,14 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs= -github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= -github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= -github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= +github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU= +github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/mutablelogic/go-client v1.4.9 h1:1JHLha6u0u0mEQEHc4K0Pq6EJMwd8F0DR/ahQrzTAlA= -github.com/mutablelogic/go-client v1.4.9/go.mod h1:g8c6RlvIC0wC5rpoqtqk7eznBxormwrxArxH9I5rNRQ= +github.com/mutablelogic/go-client v1.4.10 h1:Jb+H9QWiAEIieMzl/WcsPfwnZgT3nTRVOwOd7+sN0Z8= +github.com/mutablelogic/go-client v1.4.10/go.mod h1:g8c6RlvIC0wC5rpoqtqk7eznBxormwrxArxH9I5rNRQ= github.com/mutablelogic/go-tokenizer v0.0.3 h1:6oaa80TaAl+nVpd+M9QhlJPbP7y5/thq4d0dKjreiLs= github.com/mutablelogic/go-tokenizer v0.0.3/go.mod h1:zdAyIhfqUKxFXb8MwChbXNwMOZt/5NlUylmx6Qjr4v8= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -79,65 +79,67 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 h1:hhPGP3zvvy1xWT9RTy970wlniSxFttBIsAK1gvMguJM= -go.opentelemetry.io/contrib/bridges/otelslog v0.18.0/go.mod h1:twJF7inoMza6kxMcF8JOdL3mPmtOZu7GEr34CUNE6Dg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 h1:8UQVDcZxOJLtX6gxtDt3vY2WTgvZqMQRzjsqiIHQdkc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0/go.mod h1:2lmweYCiHYpEjQ/lSJBYhj9jP1zvCvQW4BqL9dnT7FQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= -go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= -go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= -go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= -go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= -go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/contrib/bridges/otelslog v0.19.0 h1:5RgvxieNq9tS3ewrV1vnODvbHPfKUIJcYtF9Cvz+6aQ= +go.opentelemetry.io/contrib/bridges/otelslog v0.19.0/go.mod h1:iTBIdNwx/xmUhfgJs6+84S4dIK059811cO1eUBjKcHY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.20.0 h1:rydZ9sxbcFdm/oWrVyfLTjHIygMgv0bEeMd+3B/BvoM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.20.0/go.mod h1:earQ25dooT0Hhspq59DZ8YCC50jWfOlFEeWoxy/P444= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0 h1:owlhcJ3QO3X0YTDTCcDZ4V+6aVDkWbNmBoQ5NUp7Oww= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0/go.mod h1:MP4eemTiI9zC8fgg+DYynhYDYf3ba72S376TvP+Ye0Q= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 h1:SUplec5dp06reu1zaXmOXdvqH398taqrDXqUl99jxSc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0/go.mod h1:ho2g4N+ane+swq5I/VBkKWnRDY4kUINH3FuqyZqX/Ug= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 h1:RuynHbfU8JUEw7DyONgkVYg2SVtsoF28y0LGIr69jgA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0/go.mod h1:qZF+/lBs71APw8mlnEZcqZHMzqrYrsFiJOv83lX1OGo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s= +go.opentelemetry.io/otel/log v0.20.0 h1:/5i0vuHxCLWUfChWG41K9wkM0jafruPw9NU1/RCJirs= +go.opentelemetry.io/otel/log v0.20.0/go.mod h1:wOcMcjsZpG8x7Bak7IhSi/lg8wscV2C1VdrKCLPlt0E= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/log v0.20.0 h1:vM3xI7TQgKPiSghe6urZtAkyFY7SodrSpC83CffDFuY= +go.opentelemetry.io/otel/sdk/log v0.20.0/go.mod h1:Knej2nmsTUzN79T2eeXdRsjjPcoxoq2pUyUHz9TFyyU= +go.opentelemetry.io/otel/sdk/log/logtest v0.20.0 h1:OqdRZ1guyzamK3M6LlRsmGqRrjkHWw6WZOKKli5ELpg= +go.opentelemetry.io/otel/sdk/log/logtest v0.20.0/go.mod h1:PuMIlm7zAt7c3z8zfOI5ox4iT1Z87We+PF6YoINux/M= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= -google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 h1:jQ9p21COKWjP3VwuFrNRiiOTMh3mPpN45R7SLrH/HUU= +google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7/go.mod h1:KqHwBx2upmfa1XSi1WuRvC+2VGCLtooKkfmyvRbUmqA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7 h1:eM/YSd5bBFagF51o1E745Ta7RwzpW0h+z+QDNZOgmQ8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= +google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=