From 1e71c25deb1befe82a5429123f82e55e3c1757dc Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Sat, 13 Jun 2026 12:28:29 +0100 Subject: [PATCH 1/3] test: add an in-depth test for `deprecated: true` As part of future changes, we'll be improving how `oapi-codegen` generates deprecation notices through godoc. Before we do this, we can introduce a more in-depth test case for the different areas that can be marked as deprecated, so we can validate the functionality. With help from As a starting point from **??**, we can then extend this to: - Cover at least an HTTP client and server - Add Strict Server functionality - Deprecate a parameter - Generate a deprecation on `components/response` Co-authored-by: Claude Sonnet 4.6 --- internal/test/deprecation/api.yaml | 183 +++ internal/test/deprecation/cfg.yaml | 12 + internal/test/deprecation/gen.go | 1814 +++++++++++++++++++++++++ internal/test/deprecation/generate.go | 3 + 4 files changed, 2012 insertions(+) create mode 100644 internal/test/deprecation/api.yaml create mode 100644 internal/test/deprecation/cfg.yaml create mode 100644 internal/test/deprecation/gen.go create mode 100644 internal/test/deprecation/generate.go diff --git a/internal/test/deprecation/api.yaml b/internal/test/deprecation/api.yaml new file mode 100644 index 000000000..abd0dd1ed --- /dev/null +++ b/internal/test/deprecation/api.yaml @@ -0,0 +1,183 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Marking operations and types as deprecated +components: + responses: + LegacyResponse: + description: A component-level response with a deprecated header + headers: + X-Old-Trace: + deprecated: true + x-deprecated-reason: Use X-Trace-Id instead. + schema: + type: string + X-Correlation-Id: + schema: + type: string + content: + application/json: + schema: + type: object + properties: + result: + type: string + schemas: + Client: + type: object + required: + - name + properties: + name: + type: string + id: + type: number + ClientWithExtension: + type: object + required: + - name + properties: + name: + type: string + deprecated: true + x-deprecated-reason: Don't use because reasons + id: + type: number + # NOTE that this doesn't generate, as no `deprecated: true` is set + x-deprecated-reason: NOTE you shouldn't see this, as you've not deprecated this field + deprecated_without_reason: + type: string + deprecated: true + # no `x-deprecated-reason` is set + DeprecatedObject: + type: object + deprecated: true + x-deprecated-reason: Don't use because reasons + properties: + this_is_fine: + type: string +paths: + /deprecated_endpoint: + get: + deprecated: true + x-deprecated-reason: Use another endpoint instead. + responses: + 200: + content: + application/json: + schema: + type: object + properties: + is_deprecated: + $ref: "#/components/schemas/ClientWithExtension" + not_deprecated: + type: string + /deprecated_field: + get: + parameters: + - name: old_filter + in: query + deprecated: true + x-deprecated-reason: Use new_filter instead. + schema: + type: string + - name: new_filter + in: query + schema: + type: string + responses: + 200: + content: + application/json: + schema: + type: object + properties: + is_deprecated: + $ref: "#/components/schemas/ClientWithExtension" + not_deprecated: + type: string + deprecated_on_allof: + deprecated: true + allOf: + - $ref: "#/components/schemas/Client" + deprecated_object: + $ref: "#/components/schemas/DeprecatedObject" + /deprecated_params/{old_id}: + get: + parameters: + - name: old_id + in: path + required: true + deprecated: true + x-deprecated-reason: Use new_id instead. + schema: + type: string + - name: old_header + in: header + deprecated: true + x-deprecated-reason: Use Authorization instead. + schema: + type: string + - name: old_cookie + in: cookie + deprecated: true + x-deprecated-reason: Use session header instead. + schema: + type: string + responses: + 200: + description: OK + headers: + X-Old-Token: + deprecated: true + x-deprecated-reason: Use the Authorization header instead. + schema: + type: string + content: + application/json: + schema: + type: object + properties: + result: + type: string + /deprecated_request_body: + post: + deprecated: true + x-deprecated-reason: Use /clients instead. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DeprecatedObject" + responses: + 200: + content: + application/json: + schema: + $ref: "#/components/schemas/DeprecatedObject" + /clients: + post: + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + responses: + 200: + content: + application/json: + schema: + type: object + properties: + deprecated_ref_and_field: + deprecated: true + x-deprecated-reason: This field and its type are both deprecated. + allOf: + - $ref: "#/components/schemas/DeprecatedObject" + /legacy: + get: + responses: + 200: + $ref: "#/components/responses/LegacyResponse" diff --git a/internal/test/deprecation/cfg.yaml b/internal/test/deprecation/cfg.yaml new file mode 100644 index 000000000..ca5a4dbb2 --- /dev/null +++ b/internal/test/deprecation/cfg.yaml @@ -0,0 +1,12 @@ +# yaml-language-server: $schema=../../../configuration-schema.json +package: deprecation +output: gen.go +generate: + models: true + client: true + strict-server: true + std-http-server: true +output-options: + # to make sure that all types are generated, even if they're unreferenced + skip-prune: true + client-type-name: APIClient diff --git a/internal/test/deprecation/gen.go b/internal/test/deprecation/gen.go new file mode 100644 index 000000000..626ddb9f7 --- /dev/null +++ b/internal/test/deprecation/gen.go @@ -0,0 +1,1814 @@ +//go:build go1.22 + +// Package deprecation provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. +package deprecation + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// Client defines model for Client. +type Client struct { + Id *float32 `json:"id,omitempty"` + Name string `json:"name"` +} + +// ClientWithExtension defines model for ClientWithExtension. +type ClientWithExtension struct { + // Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set + DeprecatedWithoutReason *string `json:"deprecated_without_reason,omitempty"` + Id *float32 `json:"id,omitempty"` + // Deprecated: Don't use because reasons + Name string `json:"name"` +} + +// DeprecatedObject defines model for DeprecatedObject. +type DeprecatedObject struct { + ThisIsFine *string `json:"this_is_fine,omitempty"` +} + +// LegacyResponse defines model for LegacyResponse. +type LegacyResponse struct { + Result *string `json:"result,omitempty"` +} + +// GetDeprecatedFieldParams defines parameters for GetDeprecatedField. +type GetDeprecatedFieldParams struct { + OldFilter *string `form:"old_filter,omitempty" json:"old_filter,omitempty"` + NewFilter *string `form:"new_filter,omitempty" json:"new_filter,omitempty"` +} + +// GetDeprecatedParamsOldIdParams defines parameters for GetDeprecatedParamsOldId. +type GetDeprecatedParamsOldIdParams struct { + OldHeader *string `json:"old_header,omitempty"` + OldCookie *string `form:"old_cookie,omitempty" json:"old_cookie,omitempty"` +} + +// PostClientsJSONRequestBody defines body for PostClients for application/json ContentType. +type PostClientsJSONRequestBody = Client + +// PostDeprecatedRequestBodyJSONRequestBody defines body for PostDeprecatedRequestBody for application/json ContentType. +type PostDeprecatedRequestBodyJSONRequestBody = DeprecatedObject + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// APIClient which conforms to the OpenAPI3 specification for this service. +type APIClient struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*APIClient) error + +// Creates a new APIClient, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*APIClient, error) { + // create a client with sane default values + client := APIClient{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *APIClient) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *APIClient) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // PostClientsWithBody request with any body + PostClientsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostClients(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetDeprecatedEndpoint request + GetDeprecatedEndpoint(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetDeprecatedField request + GetDeprecatedField(ctx context.Context, params *GetDeprecatedFieldParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetDeprecatedParamsOldId request + GetDeprecatedParamsOldId(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostDeprecatedRequestBodyWithBody request with any body + PostDeprecatedRequestBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostDeprecatedRequestBody(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLegacy request + GetLegacy(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *APIClient) PostClientsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostClientsRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) PostClients(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostClientsRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) GetDeprecatedEndpoint(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDeprecatedEndpointRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) GetDeprecatedField(ctx context.Context, params *GetDeprecatedFieldParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDeprecatedFieldRequest(c.Server, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) GetDeprecatedParamsOldId(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDeprecatedParamsOldIdRequest(c.Server, oldId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) PostDeprecatedRequestBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostDeprecatedRequestBodyRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) PostDeprecatedRequestBody(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostDeprecatedRequestBodyRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *APIClient) GetLegacy(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLegacyRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewPostClientsRequest calls the generic PostClients builder with application/json body +func NewPostClientsRequest(server string, body PostClientsJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostClientsRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostClientsRequestWithBody generates requests for PostClients with any type of body +func NewPostClientsRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/clients") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetDeprecatedEndpointRequest generates requests for GetDeprecatedEndpoint +func NewGetDeprecatedEndpointRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/deprecated_endpoint") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetDeprecatedFieldRequest generates requests for GetDeprecatedField +func NewGetDeprecatedFieldRequest(server string, params *GetDeprecatedFieldParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/deprecated_field") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + // queryValues collects non-styled parameters (passthrough, JSON) + // that are safe to round-trip through url.Values.Encode(). + queryValues := queryURL.Query() + // rawQueryFragments collects pre-encoded query fragments from + // styled parameters, preserving literal commas as delimiters + // per the OpenAPI spec (e.g. "color=blue,black,brown"). + var rawQueryFragments []string + + if params.OldFilter != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "old_filter", *params.OldFilter, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.NewFilter != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "new_filter", *params.NewFilter, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") + } + + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetDeprecatedParamsOldIdRequest generates requests for GetDeprecatedParamsOldId +func NewGetDeprecatedParamsOldIdRequest(server string, oldId string, params *GetDeprecatedParamsOldIdParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "old_id", oldId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/deprecated_params/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + if params.OldHeader != nil { + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithOptions("simple", false, "old_header", *params.OldHeader, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("old_header", headerParam0) + } + + } + + if params != nil { + + if params.OldCookie != nil { + var cookieParam0 string + + cookieParam0, err = runtime.StyleParamWithOptions("simple", true, "old_cookie", *params.OldCookie, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + cookie0 := &http.Cookie{ + Name: "old_cookie", + Value: cookieParam0, + } + req.AddCookie(cookie0) + } + } + return req, nil +} + +// NewPostDeprecatedRequestBodyRequest calls the generic PostDeprecatedRequestBody builder with application/json body +func NewPostDeprecatedRequestBodyRequest(server string, body PostDeprecatedRequestBodyJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostDeprecatedRequestBodyRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostDeprecatedRequestBodyRequestWithBody generates requests for PostDeprecatedRequestBody with any type of body +func NewPostDeprecatedRequestBodyRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/deprecated_request_body") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetLegacyRequest generates requests for GetLegacy +func NewGetLegacyRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/legacy") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +func (c *APIClient) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *APIClient) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // PostClientsWithBodyWithResponse request with any body + PostClientsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostClientsResponse, error) + + PostClientsWithResponse(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*PostClientsResponse, error) + + // GetDeprecatedEndpointWithResponse request + GetDeprecatedEndpointWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDeprecatedEndpointResponse, error) + + // GetDeprecatedFieldWithResponse request + GetDeprecatedFieldWithResponse(ctx context.Context, params *GetDeprecatedFieldParams, reqEditors ...RequestEditorFn) (*GetDeprecatedFieldResponse, error) + + // GetDeprecatedParamsOldIdWithResponse request + GetDeprecatedParamsOldIdWithResponse(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*GetDeprecatedParamsOldIdResponse, error) + + // PostDeprecatedRequestBodyWithBodyWithResponse request with any body + PostDeprecatedRequestBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) + + PostDeprecatedRequestBodyWithResponse(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) + + // GetLegacyWithResponse request + GetLegacyWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetLegacyResponse, error) +} + +type PostClientsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + // Deprecated: This field and its type are both deprecated. + DeprecatedRefAndField *DeprecatedObject `json:"deprecated_ref_and_field,omitempty"` + } +} + +// GetJSON200 returns JSON200 +func (r PostClientsResponse) GetJSON200() *struct { + // Deprecated: This field and its type are both deprecated. + DeprecatedRefAndField *DeprecatedObject `json:"deprecated_ref_and_field,omitempty"` +} { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r PostClientsResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r PostClientsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostClientsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostClientsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetDeprecatedEndpointResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` + } +} + +// GetJSON200 returns JSON200 +func (r GetDeprecatedEndpointResponse) GetJSON200() *struct { + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` +} { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r GetDeprecatedEndpointResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r GetDeprecatedEndpointResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDeprecatedEndpointResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetDeprecatedEndpointResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetDeprecatedFieldResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + // Deprecated: Don't use because reasons + DeprecatedObject *DeprecatedObject `json:"deprecated_object,omitempty"` + // Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set + DeprecatedOnAllof *Client `json:"deprecated_on_allof,omitempty"` + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` + } +} + +// GetJSON200 returns JSON200 +func (r GetDeprecatedFieldResponse) GetJSON200() *struct { + // Deprecated: Don't use because reasons + DeprecatedObject *DeprecatedObject `json:"deprecated_object,omitempty"` + // Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set + DeprecatedOnAllof *Client `json:"deprecated_on_allof,omitempty"` + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` +} { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r GetDeprecatedFieldResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r GetDeprecatedFieldResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDeprecatedFieldResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetDeprecatedFieldResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetDeprecatedParamsOldIdResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Result *string `json:"result,omitempty"` + } +} + +// GetJSON200 returns JSON200 +func (r GetDeprecatedParamsOldIdResponse) GetJSON200() *struct { + Result *string `json:"result,omitempty"` +} { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r GetDeprecatedParamsOldIdResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r GetDeprecatedParamsOldIdResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDeprecatedParamsOldIdResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetDeprecatedParamsOldIdResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type PostDeprecatedRequestBodyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *DeprecatedObject +} + +// GetJSON200 returns JSON200 +func (r PostDeprecatedRequestBodyResponse) GetJSON200() *DeprecatedObject { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r PostDeprecatedRequestBodyResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r PostDeprecatedRequestBodyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostDeprecatedRequestBodyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostDeprecatedRequestBodyResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetLegacyResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *LegacyResponse +} + +// GetJSON200 returns JSON200 +func (r GetLegacyResponse) GetJSON200() *LegacyResponse { + return r.JSON200 +} + +// GetBody returns the raw response body bytes (Body) +func (r GetLegacyResponse) GetBody() []byte { + return r.Body +} + +// Status returns HTTPResponse.Status +func (r GetLegacyResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLegacyResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLegacyResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +// PostClientsWithBodyWithResponse request with arbitrary body returning *PostClientsResponse +func (c *ClientWithResponses) PostClientsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostClientsResponse, error) { + rsp, err := c.PostClientsWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostClientsResponse(rsp) +} + +func (c *ClientWithResponses) PostClientsWithResponse(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*PostClientsResponse, error) { + rsp, err := c.PostClients(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostClientsResponse(rsp) +} + +// GetDeprecatedEndpointWithResponse request returning *GetDeprecatedEndpointResponse +func (c *ClientWithResponses) GetDeprecatedEndpointWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDeprecatedEndpointResponse, error) { + rsp, err := c.GetDeprecatedEndpoint(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetDeprecatedEndpointResponse(rsp) +} + +// GetDeprecatedFieldWithResponse request returning *GetDeprecatedFieldResponse +func (c *ClientWithResponses) GetDeprecatedFieldWithResponse(ctx context.Context, params *GetDeprecatedFieldParams, reqEditors ...RequestEditorFn) (*GetDeprecatedFieldResponse, error) { + rsp, err := c.GetDeprecatedField(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetDeprecatedFieldResponse(rsp) +} + +// GetDeprecatedParamsOldIdWithResponse request returning *GetDeprecatedParamsOldIdResponse +func (c *ClientWithResponses) GetDeprecatedParamsOldIdWithResponse(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*GetDeprecatedParamsOldIdResponse, error) { + rsp, err := c.GetDeprecatedParamsOldId(ctx, oldId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetDeprecatedParamsOldIdResponse(rsp) +} + +// PostDeprecatedRequestBodyWithBodyWithResponse request with arbitrary body returning *PostDeprecatedRequestBodyResponse +func (c *ClientWithResponses) PostDeprecatedRequestBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) { + rsp, err := c.PostDeprecatedRequestBodyWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostDeprecatedRequestBodyResponse(rsp) +} + +func (c *ClientWithResponses) PostDeprecatedRequestBodyWithResponse(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) { + rsp, err := c.PostDeprecatedRequestBody(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostDeprecatedRequestBodyResponse(rsp) +} + +// GetLegacyWithResponse request returning *GetLegacyResponse +func (c *ClientWithResponses) GetLegacyWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetLegacyResponse, error) { + rsp, err := c.GetLegacy(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLegacyResponse(rsp) +} + +// ParsePostClientsResponse parses an HTTP response from a PostClientsWithResponse call +func ParsePostClientsResponse(rsp *http.Response) (*PostClientsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostClientsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + // Deprecated: This field and its type are both deprecated. + DeprecatedRefAndField *DeprecatedObject `json:"deprecated_ref_and_field,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetDeprecatedEndpointResponse parses an HTTP response from a GetDeprecatedEndpointWithResponse call +func ParseGetDeprecatedEndpointResponse(rsp *http.Response) (*GetDeprecatedEndpointResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDeprecatedEndpointResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetDeprecatedFieldResponse parses an HTTP response from a GetDeprecatedFieldWithResponse call +func ParseGetDeprecatedFieldResponse(rsp *http.Response) (*GetDeprecatedFieldResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDeprecatedFieldResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + // Deprecated: Don't use because reasons + DeprecatedObject *DeprecatedObject `json:"deprecated_object,omitempty"` + // Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set + DeprecatedOnAllof *Client `json:"deprecated_on_allof,omitempty"` + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetDeprecatedParamsOldIdResponse parses an HTTP response from a GetDeprecatedParamsOldIdWithResponse call +func ParseGetDeprecatedParamsOldIdResponse(rsp *http.Response) (*GetDeprecatedParamsOldIdResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDeprecatedParamsOldIdResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Result *string `json:"result,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostDeprecatedRequestBodyResponse parses an HTTP response from a PostDeprecatedRequestBodyWithResponse call +func ParsePostDeprecatedRequestBodyResponse(rsp *http.Response) (*PostDeprecatedRequestBodyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostDeprecatedRequestBodyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest DeprecatedObject + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetLegacyResponse parses an HTTP response from a GetLegacyWithResponse call +func ParseGetLegacyResponse(rsp *http.Response) (*GetLegacyResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLegacyResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest LegacyResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (POST /clients) + PostClients(w http.ResponseWriter, r *http.Request) + + // (GET /deprecated_endpoint) + GetDeprecatedEndpoint(w http.ResponseWriter, r *http.Request) + + // (GET /deprecated_field) + GetDeprecatedField(w http.ResponseWriter, r *http.Request, params GetDeprecatedFieldParams) + + // (GET /deprecated_params/{old_id}) + GetDeprecatedParamsOldId(w http.ResponseWriter, r *http.Request, oldId string, params GetDeprecatedParamsOldIdParams) + + // (POST /deprecated_request_body) + PostDeprecatedRequestBody(w http.ResponseWriter, r *http.Request) + + // (GET /legacy) + GetLegacy(w http.ResponseWriter, r *http.Request) +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +type MiddlewareFunc func(http.Handler) http.Handler + +// PostClients operation middleware +func (siw *ServerInterfaceWrapper) PostClients(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.PostClients(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeprecatedEndpoint operation middleware +func (siw *ServerInterfaceWrapper) GetDeprecatedEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeprecatedEndpoint(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeprecatedField operation middleware +func (siw *ServerInterfaceWrapper) GetDeprecatedField(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeprecatedFieldParams + + // ------------- Optional query parameter "old_filter" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "old_filter", r.URL.Query(), ¶ms.OldFilter, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "old_filter"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "old_filter", Err: err}) + } + return + } + + // ------------- Optional query parameter "new_filter" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "new_filter", r.URL.Query(), ¶ms.NewFilter, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "new_filter"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "new_filter", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeprecatedField(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeprecatedParamsOldId operation middleware +func (siw *ServerInterfaceWrapper) GetDeprecatedParamsOldId(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "old_id" ------------- + var oldId string + + err = runtime.BindStyledParameterWithOptions("simple", "old_id", r.PathValue("old_id"), &oldId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "old_id", Err: err}) + return + } + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeprecatedParamsOldIdParams + + headers := r.Header + + // ------------- Optional header parameter "old_header" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("old_header")]; found { + var OldHeader string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "old_header", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "old_header", valueList[0], &OldHeader, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "old_header", Err: err}) + return + } + + params.OldHeader = &OldHeader + + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("old_cookie"); err == nil { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "old_cookie", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "old_cookie", Err: err}) + return + } + params.OldCookie = &value + + } + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeprecatedParamsOldId(w, r, oldId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// PostDeprecatedRequestBody operation middleware +func (siw *ServerInterfaceWrapper) PostDeprecatedRequestBody(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.PostDeprecatedRequestBody(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLegacy operation middleware +func (siw *ServerInterfaceWrapper) GetLegacy(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLegacy(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +type UnescapedCookieParamError struct { + ParamName string + Err error +} + +func (e *UnescapedCookieParamError) Error() string { + return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) +} + +func (e *UnescapedCookieParamError) Unwrap() error { + return e.Err +} + +type UnmarshalingParamError struct { + ParamName string + Err error +} + +func (e *UnmarshalingParamError) Error() string { + return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) +} + +func (e *UnmarshalingParamError) Unwrap() error { + return e.Err +} + +type RequiredParamError struct { + ParamName string +} + +func (e *RequiredParamError) Error() string { + return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) +} + +type RequiredHeaderError struct { + ParamName string + Err error +} + +func (e *RequiredHeaderError) Error() string { + return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) +} + +func (e *RequiredHeaderError) Unwrap() error { + return e.Err +} + +type InvalidParamFormatError struct { + ParamName string + Err error +} + +func (e *InvalidParamFormatError) Error() string { + return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) +} + +func (e *InvalidParamFormatError) Unwrap() error { + return e.Err +} + +type TooManyValuesForParamError struct { + ParamName string + Count int +} + +func (e *TooManyValuesForParamError) Error() string { + return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) +} + +// Handler creates http.Handler with routing matching OpenAPI spec. +func Handler(si ServerInterface) http.Handler { + return HandlerWithOptions(si, StdHTTPServerOptions{}) +} + +// ServeMux is an abstraction of [http.ServeMux]. +type ServeMux interface { + HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) + http.Handler +} + +type StdHTTPServerOptions struct { + BaseURL string + BaseRouter ServeMux + Middlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. +func HandlerFromMux(si ServerInterface, m ServeMux) http.Handler { + return HandlerWithOptions(si, StdHTTPServerOptions{ + BaseRouter: m, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, m ServeMux, baseURL string) http.Handler { + return HandlerWithOptions(si, StdHTTPServerOptions{ + BaseURL: baseURL, + BaseRouter: m, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.Handler { + m := options.BaseRouter + + if m == nil { + m = http.NewServeMux() + } + if options.ErrorHandlerFunc == nil { + options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandlerFunc: options.ErrorHandlerFunc, + } + + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/clients", wrapper.PostClients) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/deprecated_endpoint", wrapper.GetDeprecatedEndpoint) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/deprecated_field", wrapper.GetDeprecatedField) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/deprecated_params/{old_id}", wrapper.GetDeprecatedParamsOldId) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/deprecated_request_body", wrapper.PostDeprecatedRequestBody) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/legacy", wrapper.GetLegacy) + + return m +} + +type LegacyResponseResponseHeaders struct { + XCorrelationId *string + XOldTrace *string +} +type LegacyResponseJSONResponse struct { + Body struct { + Result *string `json:"result,omitempty"` + } + + Headers LegacyResponseResponseHeaders +} + +type PostClientsRequestObject struct { + Body *PostClientsJSONRequestBody +} + +type PostClientsResponseObject interface { + VisitPostClientsResponse(w http.ResponseWriter) error +} + +type PostClients200JSONResponse struct { + // Deprecated: This field and its type are both deprecated. + DeprecatedRefAndField *DeprecatedObject `json:"deprecated_ref_and_field,omitempty"` +} + +func (response PostClients200JSONResponse) VisitPostClientsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetDeprecatedEndpointRequestObject struct { +} + +type GetDeprecatedEndpointResponseObject interface { + VisitGetDeprecatedEndpointResponse(w http.ResponseWriter) error +} + +type GetDeprecatedEndpoint200JSONResponse struct { + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` +} + +func (response GetDeprecatedEndpoint200JSONResponse) VisitGetDeprecatedEndpointResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetDeprecatedFieldRequestObject struct { + Params GetDeprecatedFieldParams +} + +type GetDeprecatedFieldResponseObject interface { + VisitGetDeprecatedFieldResponse(w http.ResponseWriter) error +} + +type GetDeprecatedField200JSONResponse struct { + // Deprecated: Don't use because reasons + DeprecatedObject *DeprecatedObject `json:"deprecated_object,omitempty"` + // Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set + DeprecatedOnAllof *Client `json:"deprecated_on_allof,omitempty"` + IsDeprecated *ClientWithExtension `json:"is_deprecated,omitempty"` + NotDeprecated *string `json:"not_deprecated,omitempty"` +} + +func (response GetDeprecatedField200JSONResponse) VisitGetDeprecatedFieldResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetDeprecatedParamsOldIdRequestObject struct { + OldId string `json:"old_id"` + Params GetDeprecatedParamsOldIdParams +} + +type GetDeprecatedParamsOldIdResponseObject interface { + VisitGetDeprecatedParamsOldIdResponse(w http.ResponseWriter) error +} + +type GetDeprecatedParamsOldId200ResponseHeaders struct { + XOldToken *string +} + +type GetDeprecatedParamsOldId200JSONResponse struct { + Body struct { + Result *string `json:"result,omitempty"` + } + Headers GetDeprecatedParamsOldId200ResponseHeaders +} + +func (response GetDeprecatedParamsOldId200JSONResponse) VisitGetDeprecatedParamsOldIdResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + if response.Headers.XOldToken != nil { + w.Header().Set("X-Old-Token", fmt.Sprint(*response.Headers.XOldToken)) + } + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type PostDeprecatedRequestBodyRequestObject struct { + Body *PostDeprecatedRequestBodyJSONRequestBody +} + +type PostDeprecatedRequestBodyResponseObject interface { + VisitPostDeprecatedRequestBodyResponse(w http.ResponseWriter) error +} + +type PostDeprecatedRequestBody200JSONResponse DeprecatedObject + +func (response PostDeprecatedRequestBody200JSONResponse) VisitPostDeprecatedRequestBodyResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetLegacyRequestObject struct { +} + +type GetLegacyResponseObject interface { + VisitGetLegacyResponse(w http.ResponseWriter) error +} + +type GetLegacy200JSONResponse struct{ LegacyResponseJSONResponse } + +func (response GetLegacy200JSONResponse) VisitGetLegacyResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + if response.Headers.XCorrelationId != nil { + w.Header().Set("X-Correlation-Id", fmt.Sprint(*response.Headers.XCorrelationId)) + } + if response.Headers.XOldTrace != nil { + w.Header().Set("X-Old-Trace", fmt.Sprint(*response.Headers.XOldTrace)) + } + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (POST /clients) + PostClients(ctx context.Context, request PostClientsRequestObject) (PostClientsResponseObject, error) + + // (GET /deprecated_endpoint) + GetDeprecatedEndpoint(ctx context.Context, request GetDeprecatedEndpointRequestObject) (GetDeprecatedEndpointResponseObject, error) + + // (GET /deprecated_field) + GetDeprecatedField(ctx context.Context, request GetDeprecatedFieldRequestObject) (GetDeprecatedFieldResponseObject, error) + + // (GET /deprecated_params/{old_id}) + GetDeprecatedParamsOldId(ctx context.Context, request GetDeprecatedParamsOldIdRequestObject) (GetDeprecatedParamsOldIdResponseObject, error) + + // (POST /deprecated_request_body) + PostDeprecatedRequestBody(ctx context.Context, request PostDeprecatedRequestBodyRequestObject) (PostDeprecatedRequestBodyResponseObject, error) + + // (GET /legacy) + GetLegacy(ctx context.Context, request GetLegacyRequestObject) (GetLegacyResponseObject, error) +} + +type StrictHandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc + +type StrictHTTPServerOptions struct { + RequestErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) + ResponseErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictHTTPServerOptions{ + RequestErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + }, + ResponseErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} +} + +type strictHandler struct { + ssi StrictServerInterface + middlewares []StrictMiddlewareFunc + options StrictHTTPServerOptions +} + +// PostClients operation middleware +func (sh *strictHandler) PostClients(w http.ResponseWriter, r *http.Request) { + var request PostClientsRequestObject + + var body PostClientsJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.PostClients(ctx, request.(PostClientsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "PostClients") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(PostClientsResponseObject); ok { + if err := validResponse.VisitPostClientsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetDeprecatedEndpoint operation middleware +func (sh *strictHandler) GetDeprecatedEndpoint(w http.ResponseWriter, r *http.Request) { + var request GetDeprecatedEndpointRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetDeprecatedEndpoint(ctx, request.(GetDeprecatedEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetDeprecatedEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetDeprecatedEndpointResponseObject); ok { + if err := validResponse.VisitGetDeprecatedEndpointResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetDeprecatedField operation middleware +func (sh *strictHandler) GetDeprecatedField(w http.ResponseWriter, r *http.Request, params GetDeprecatedFieldParams) { + var request GetDeprecatedFieldRequestObject + + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetDeprecatedField(ctx, request.(GetDeprecatedFieldRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetDeprecatedField") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetDeprecatedFieldResponseObject); ok { + if err := validResponse.VisitGetDeprecatedFieldResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetDeprecatedParamsOldId operation middleware +func (sh *strictHandler) GetDeprecatedParamsOldId(w http.ResponseWriter, r *http.Request, oldId string, params GetDeprecatedParamsOldIdParams) { + var request GetDeprecatedParamsOldIdRequestObject + + request.OldId = oldId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetDeprecatedParamsOldId(ctx, request.(GetDeprecatedParamsOldIdRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetDeprecatedParamsOldId") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetDeprecatedParamsOldIdResponseObject); ok { + if err := validResponse.VisitGetDeprecatedParamsOldIdResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// PostDeprecatedRequestBody operation middleware +func (sh *strictHandler) PostDeprecatedRequestBody(w http.ResponseWriter, r *http.Request) { + var request PostDeprecatedRequestBodyRequestObject + + var body PostDeprecatedRequestBodyJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.PostDeprecatedRequestBody(ctx, request.(PostDeprecatedRequestBodyRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "PostDeprecatedRequestBody") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(PostDeprecatedRequestBodyResponseObject); ok { + if err := validResponse.VisitPostDeprecatedRequestBodyResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetLegacy operation middleware +func (sh *strictHandler) GetLegacy(w http.ResponseWriter, r *http.Request) { + var request GetLegacyRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetLegacy(ctx, request.(GetLegacyRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetLegacy") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetLegacyResponseObject); ok { + if err := validResponse.VisitGetLegacyResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} diff --git a/internal/test/deprecation/generate.go b/internal/test/deprecation/generate.go new file mode 100644 index 000000000..9b7644a3d --- /dev/null +++ b/internal/test/deprecation/generate.go @@ -0,0 +1,3 @@ +package deprecation + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml From c390cb37cd1a70bea0a1121cfb673957fb9ae006 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Sat, 13 Jun 2026 12:29:00 +0100 Subject: [PATCH 2/3] fix: deprecate **??** This adds a new **??**, dep-reason fix: emit deprecation notice on deprecated type definitions Types defined in components/schemas (and elsewhere) with deprecated:true now get a // Deprecated: comment as the final paragraph of their doc comment, which godoc and IDEs recognise as a deprecation warning. Adds DocComment() and DeprecationComment() to TypeDefinition, and updates typedef.tmpl to call DocComment() instead of inlining the description logic. Co-authored-by: Claude Sonnet 4.6 --- internal/test/deprecation/gen.go | 35 ++++++++++- pkg/codegen/operations.go | 47 +++++++++++++-- pkg/codegen/operations_test.go | 58 +++++++++++++++++++ pkg/codegen/schema.go | 30 ++++++++++ pkg/codegen/templates/chi/chi-interface.tmpl | 8 ++- .../templates/client-with-responses.tmpl | 16 +++-- pkg/codegen/templates/client.tmpl | 15 +++-- .../templates/echo/echo-interface.tmpl | 4 +- .../templates/echo/v5/echo-interface.tmpl | 4 +- .../templates/fiber/fiber-interface.tmpl | 4 +- pkg/codegen/templates/gin/gin-interface.tmpl | 4 +- .../templates/gorilla/gorilla-interface.tmpl | 4 +- .../templates/iris/iris-interface.tmpl | 4 +- .../templates/stdhttp/std-http-interface.tmpl | 4 +- .../strict/strict-fiber-interface.tmpl | 4 +- .../templates/strict/strict-interface.tmpl | 7 ++- .../strict/strict-iris-interface.tmpl | 4 +- .../templates/strict/strict-responses.tmpl | 3 +- pkg/codegen/templates/typedef.tmpl | 2 +- 19 files changed, 228 insertions(+), 29 deletions(-) diff --git a/internal/test/deprecation/gen.go b/internal/test/deprecation/gen.go index 626ddb9f7..2da9f77c8 100644 --- a/internal/test/deprecation/gen.go +++ b/internal/test/deprecation/gen.go @@ -35,6 +35,8 @@ type ClientWithExtension struct { } // DeprecatedObject defines model for DeprecatedObject. +// +// Deprecated: Don't use because reasons type DeprecatedObject struct { ThisIsFine *string `json:"this_is_fine,omitempty"` } @@ -46,13 +48,16 @@ type LegacyResponse struct { // GetDeprecatedFieldParams defines parameters for GetDeprecatedField. type GetDeprecatedFieldParams struct { + // Deprecated: Use new_filter instead. OldFilter *string `form:"old_filter,omitempty" json:"old_filter,omitempty"` NewFilter *string `form:"new_filter,omitempty" json:"new_filter,omitempty"` } // GetDeprecatedParamsOldIdParams defines parameters for GetDeprecatedParamsOldId. type GetDeprecatedParamsOldIdParams struct { + // Deprecated: Use Authorization instead. OldHeader *string `json:"old_header,omitempty"` + // Deprecated: Use session header instead. OldCookie *string `form:"old_cookie,omitempty" json:"old_cookie,omitempty"` } @@ -141,6 +146,8 @@ type ClientInterface interface { PostClients(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) // GetDeprecatedEndpoint request + // + // Deprecated: Use another endpoint instead. GetDeprecatedEndpoint(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) // GetDeprecatedField request @@ -150,8 +157,11 @@ type ClientInterface interface { GetDeprecatedParamsOldId(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*http.Response, error) // PostDeprecatedRequestBodyWithBody request with any body + // + // Deprecated: Use /clients instead. PostDeprecatedRequestBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + // Deprecated: Use /clients instead. PostDeprecatedRequestBody(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) // GetLegacy request @@ -182,6 +192,7 @@ func (c *APIClient) PostClients(ctx context.Context, body PostClientsJSONRequest return c.Client.Do(req) } +// Deprecated: Use another endpoint instead. func (c *APIClient) GetDeprecatedEndpoint(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetDeprecatedEndpointRequest(c.Server) if err != nil { @@ -218,6 +229,7 @@ func (c *APIClient) GetDeprecatedParamsOldId(ctx context.Context, oldId string, return c.Client.Do(req) } +// Deprecated: Use /clients instead. func (c *APIClient) PostDeprecatedRequestBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewPostDeprecatedRequestBodyRequestWithBody(c.Server, contentType, body) if err != nil { @@ -230,6 +242,7 @@ func (c *APIClient) PostDeprecatedRequestBodyWithBody(ctx context.Context, conte return c.Client.Do(req) } +// Deprecated: Use /clients instead. func (c *APIClient) PostDeprecatedRequestBody(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewPostDeprecatedRequestBodyRequest(c.Server, body) if err != nil { @@ -569,6 +582,8 @@ type ClientWithResponsesInterface interface { PostClientsWithResponse(ctx context.Context, body PostClientsJSONRequestBody, reqEditors ...RequestEditorFn) (*PostClientsResponse, error) // GetDeprecatedEndpointWithResponse request + // + // Deprecated: Use another endpoint instead. GetDeprecatedEndpointWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDeprecatedEndpointResponse, error) // GetDeprecatedFieldWithResponse request @@ -578,8 +593,11 @@ type ClientWithResponsesInterface interface { GetDeprecatedParamsOldIdWithResponse(ctx context.Context, oldId string, params *GetDeprecatedParamsOldIdParams, reqEditors ...RequestEditorFn) (*GetDeprecatedParamsOldIdResponse, error) // PostDeprecatedRequestBodyWithBodyWithResponse request with any body + // + // Deprecated: Use /clients instead. PostDeprecatedRequestBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) + // Deprecated: Use /clients instead. PostDeprecatedRequestBodyWithResponse(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) // GetLegacyWithResponse request @@ -874,6 +892,8 @@ func (c *ClientWithResponses) PostClientsWithResponse(ctx context.Context, body } // GetDeprecatedEndpointWithResponse request returning *GetDeprecatedEndpointResponse +// +// Deprecated: Use another endpoint instead. func (c *ClientWithResponses) GetDeprecatedEndpointWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDeprecatedEndpointResponse, error) { rsp, err := c.GetDeprecatedEndpoint(ctx, reqEditors...) if err != nil { @@ -901,6 +921,8 @@ func (c *ClientWithResponses) GetDeprecatedParamsOldIdWithResponse(ctx context.C } // PostDeprecatedRequestBodyWithBodyWithResponse request with arbitrary body returning *PostDeprecatedRequestBodyResponse +// +// Deprecated: Use /clients instead. func (c *ClientWithResponses) PostDeprecatedRequestBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) { rsp, err := c.PostDeprecatedRequestBodyWithBody(ctx, contentType, body, reqEditors...) if err != nil { @@ -909,6 +931,7 @@ func (c *ClientWithResponses) PostDeprecatedRequestBodyWithBodyWithResponse(ctx return ParsePostDeprecatedRequestBodyResponse(rsp) } +// Deprecated: Use /clients instead. func (c *ClientWithResponses) PostDeprecatedRequestBodyWithResponse(ctx context.Context, body PostDeprecatedRequestBodyJSONRequestBody, reqEditors ...RequestEditorFn) (*PostDeprecatedRequestBodyResponse, error) { rsp, err := c.PostDeprecatedRequestBody(ctx, body, reqEditors...) if err != nil { @@ -1104,6 +1127,8 @@ type ServerInterface interface { PostClients(w http.ResponseWriter, r *http.Request) // (GET /deprecated_endpoint) + // + // Deprecated: Use another endpoint instead. GetDeprecatedEndpoint(w http.ResponseWriter, r *http.Request) // (GET /deprecated_field) @@ -1113,6 +1138,8 @@ type ServerInterface interface { GetDeprecatedParamsOldId(w http.ResponseWriter, r *http.Request, oldId string, params GetDeprecatedParamsOldIdParams) // (POST /deprecated_request_body) + // + // Deprecated: Use /clients instead. PostDeprecatedRequestBody(w http.ResponseWriter, r *http.Request) // (GET /legacy) @@ -1427,7 +1454,8 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H type LegacyResponseResponseHeaders struct { XCorrelationId *string - XOldTrace *string + // Deprecated: Use X-Trace-Id instead. + XOldTrace *string } type LegacyResponseJSONResponse struct { Body struct { @@ -1525,6 +1553,7 @@ type GetDeprecatedParamsOldIdResponseObject interface { } type GetDeprecatedParamsOldId200ResponseHeaders struct { + // Deprecated: Use the Authorization header instead. XOldToken *string } @@ -1606,6 +1635,8 @@ type StrictServerInterface interface { PostClients(ctx context.Context, request PostClientsRequestObject) (PostClientsResponseObject, error) // (GET /deprecated_endpoint) + // + // Deprecated: Use another endpoint instead. GetDeprecatedEndpoint(ctx context.Context, request GetDeprecatedEndpointRequestObject) (GetDeprecatedEndpointResponseObject, error) // (GET /deprecated_field) @@ -1615,6 +1646,8 @@ type StrictServerInterface interface { GetDeprecatedParamsOldId(ctx context.Context, request GetDeprecatedParamsOldIdRequestObject) (GetDeprecatedParamsOldIdResponseObject, error) // (POST /deprecated_request_body) + // + // Deprecated: Use /clients instead. PostDeprecatedRequestBody(ctx context.Context, request PostDeprecatedRequestBodyRequestObject) (PostDeprecatedRequestBodyResponseObject, error) // (GET /legacy) diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 736a8ea1b..b3bf04662 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -413,6 +413,20 @@ func (o *OperationDefinition) SummaryAsComment() string { return strings.Join(parts, "\n") } +// DeprecationComment returns a Go-style deprecation comment if the operation is deprecated, otherwise returns an empty string. +func (o *OperationDefinition) DeprecationComment() string { + if o.Spec == nil || !o.Spec.Deprecated { + return "" + } + reason := "this operation has been marked as deprecated upstream, but no `x-deprecated-reason` was set" + if extension, ok := o.Spec.Extensions[extDeprecationReason]; ok { + if r, err := extParseDeprecationReason(extension); err == nil { + reason = r + } + } + return DeprecationComment(reason) +} + // GetResponseTypeDefinitions produces a list of type definitions for a given Operation for the response // types which we know how to parse. These will be turned into fields on a // response object for automatic deserialization of responses in the generated @@ -701,11 +715,25 @@ func (r ResponseContentDefinition) IsStreamingContentType() bool { } type ResponseHeaderDefinition struct { - Name string - GoName string - Schema Schema - Required bool - Nullable bool + Name string + GoName string + Schema Schema + Required bool + Nullable bool + Deprecated bool + DeprecationReason string +} + +// DeprecationComment returns a Go-style deprecation comment if the header is deprecated, otherwise returns an empty string. +func (h ResponseHeaderDefinition) DeprecationComment() string { + if !h.Deprecated { + return "" + } + reason := h.DeprecationReason + if reason == "" { + reason = "this header has been marked as deprecated upstream, but no `x-deprecated-reason` was set" + } + return DeprecationComment(reason) } // GoTypeDef returns the Go type string for this header, applying pointer or @@ -1155,6 +1183,14 @@ func GenerateResponseDefinitions(operationID string, responses map[string]*opena Required: header.Value.Required || globalState.options.Compatibility.HeadersImplicitlyRequired, Nullable: nullable, } + if header.Value.Deprecated { + headerDefinition.Deprecated = true + if extension, ok := header.Value.Extensions[extDeprecationReason]; ok { + if r, err := extParseDeprecationReason(extension); err == nil { + headerDefinition.DeprecationReason = r + } + } + } responseHeaderDefinitions = append(responseHeaderDefinitions, headerDefinition) } @@ -1256,6 +1292,7 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition { Schema: pSchema, NeedsFormTag: param.Style() == "form", Extensions: extensions, + Deprecated: param.Spec.Deprecated, } s.Properties = append(s.Properties, prop) } diff --git a/pkg/codegen/operations_test.go b/pkg/codegen/operations_test.go index fae988bbf..6b7efb751 100644 --- a/pkg/codegen/operations_test.go +++ b/pkg/codegen/operations_test.go @@ -148,6 +148,64 @@ func TestGenerateDefaultOperationID(t *testing.T) { } } +func TestDeprecationComment(t *testing.T) { + tests := []struct { + name string + op *OperationDefinition + want string + }{ + { + name: "nil spec returns empty string", + op: &OperationDefinition{Spec: nil}, + want: "", + }, + { + name: "non-deprecated operation returns empty string", + op: &OperationDefinition{ + Spec: &openapi3.Operation{Deprecated: false}, + }, + want: "", + }, + { + name: "deprecated operation without x-deprecated-reason uses default message", + op: &OperationDefinition{ + Spec: &openapi3.Operation{Deprecated: true}, + }, + want: "// Deprecated: this operation has been marked as deprecated upstream, but no `x-deprecated-reason` was set", + }, + { + name: "deprecated operation with x-deprecated-reason uses the reason", + op: &OperationDefinition{ + Spec: &openapi3.Operation{ + Deprecated: true, + Extensions: map[string]any{ + "x-deprecated-reason": "Use /v2/foo instead.", + }, + }, + }, + want: "// Deprecated: Use /v2/foo instead.", + }, + { + name: "deprecated operation with non-string x-deprecated-reason falls back to default message", + op: &OperationDefinition{ + Spec: &openapi3.Operation{ + Deprecated: true, + Extensions: map[string]any{ + "x-deprecated-reason": 42, + }, + }, + }, + want: "// Deprecated: this operation has been marked as deprecated upstream, but no `x-deprecated-reason` was set", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, tt.op.DeprecationComment()) + }) + } +} + func TestJsonTag(t *testing.T) { t.Run("required param with no extra tags", func(t *testing.T) { pd := ParameterDefinition{ diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 2e216537f..da12c00b8 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -269,6 +269,36 @@ type TypeDefinition struct { ForceEnumPrefix bool } +// DeprecationComment returns a Go-style deprecation comment if the type is +// deprecated, otherwise returns an empty string. +func (t TypeDefinition) DeprecationComment() string { + if t.Schema.OAPISchema == nil || !t.Schema.OAPISchema.Deprecated { + return "" + } + reason := "this type has been marked as deprecated upstream, but no `x-deprecated-reason` was set" + if extension, ok := t.Schema.OAPISchema.Extensions[extDeprecationReason]; ok { + if r, err := extParseDeprecationReason(extension); err == nil { + reason = r + } + } + return DeprecationComment(reason) +} + +// DocComment returns the full Go doc comment for the type, including the +// deprecation notice as a separate paragraph when the type is deprecated. +func (t TypeDefinition) DocComment() string { + var comment string + if t.Schema.Description != "" { + comment = StringWithTypeNameToGoComment(t.Schema.Description, t.TypeName) + } else { + comment = fmt.Sprintf("// %s defines model for %s.", t.TypeName, t.JsonName) + } + if dc := t.DeprecationComment(); dc != "" { + comment += "\n//\n" + dc + } + return comment +} + // ResponseTypeDefinition is an extension of TypeDefinition, specifically for // response unmarshaling in ClientWithResponses. type ResponseTypeDefinition struct { diff --git a/pkg/codegen/templates/chi/chi-interface.tmpl b/pkg/codegen/templates/chi/chi-interface.tmpl index bec8452e7..a218401f9 100644 --- a/pkg/codegen/templates/chi/chi-interface.tmpl +++ b/pkg/codegen/templates/chi/chi-interface.tmpl @@ -2,7 +2,9 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) {{end}}{{end}} } @@ -11,7 +13,9 @@ type ServerInterface interface { type Unimplemented struct {} {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) - func (_ Unimplemented) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { +{{with .DeprecationComment}}// +{{.}} +{{end}} func (_ Unimplemented) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { w.WriteHeader(http.StatusNotImplemented) } {{end}}{{end}} \ No newline at end of file diff --git a/pkg/codegen/templates/client-with-responses.tmpl b/pkg/codegen/templates/client-with-responses.tmpl index b2c954663..ba5c1c89f 100644 --- a/pkg/codegen/templates/client-with-responses.tmpl +++ b/pkg/codegen/templates/client-with-responses.tmpl @@ -33,11 +33,15 @@ type ClientWithResponsesInterface interface { {{$hasParams := .RequiresParamObject -}} {{$pathParams := .PathParams -}} {{$opid := .OperationId -}} +{{$deprecationComment := .DeprecationComment -}} // {{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse request{{if .HasBody}} with any body{{end}} - {{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse(ctx context.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) + {{with .DeprecationComment}}// + {{.}} + {{end}}{{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse(ctx context.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) {{range .Bodies}} {{if .IsSupportedByClient -}} - {{$opid}}{{.Suffix}}WithResponse(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) + {{with $deprecationComment}}{{.}} + {{end -}}{{$opid}}{{.Suffix}}WithResponse(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) {{end -}} {{end}}{{/* range .Bodies */}} {{end}}{{/* range . $opid := .OperationId */}} @@ -105,10 +109,13 @@ func (r {{genResponseTypeName $opid | ucFirst}}) ContentType() string { {{range .}} {{$opid := .OperationId -}} +{{$deprecationComment := .DeprecationComment -}} {{/* Generate client methods (with responses)*/}} // {{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse request{{if .HasBody}} with arbitrary body{{end}} returning *{{genResponseTypeName $opid}} -func (c *ClientWithResponses) {{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse(ctx context.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error){ +{{with $deprecationComment}}// +{{.}} +{{end}}func (c *ClientWithResponses) {{$opid}}{{if .HasBody}}WithBody{{end}}WithResponse(ctx context.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error){ rsp, err := c.{{$opid}}{{if .HasBody}}WithBody{{end}}(ctx{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}{{if .HasBody}}, contentType, body{{end}}, reqEditors...) if err != nil { return nil, err @@ -121,7 +128,8 @@ func (c *ClientWithResponses) {{$opid}}{{if .HasBody}}WithBody{{end}}WithRespons {{$bodyRequired := .BodyRequired -}} {{range .Bodies}} {{if .IsSupportedByClient -}} -func (c *ClientWithResponses) {{$opid}}{{.Suffix}}WithResponse(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) { +{{with $deprecationComment}}{{.}} +{{end}}func (c *ClientWithResponses) {{$opid}}{{.Suffix}}WithResponse(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*{{genResponseTypeName $opid}}, error) { rsp, err := c.{{$opid}}{{.Suffix}}(ctx{{genParamNames $pathParams}}{{if $hasParams}}, params{{end}}, body, reqEditors...) if err != nil { return nil, err diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl index 1f02997e1..f316a3dfa 100644 --- a/pkg/codegen/templates/client.tmpl +++ b/pkg/codegen/templates/client.tmpl @@ -77,11 +77,15 @@ type ClientInterface interface { {{$hasParams := .RequiresParamObject -}} {{$pathParams := .PathParams -}} {{$opid := .OperationId -}} +{{$deprecationComment := .DeprecationComment -}} // {{$opid}}{{if .HasBody}}WithBody{{end}} request{{if .HasBody}} with any body{{end}} - {{$opid}}{{if .HasBody}}WithBody{{end}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*http.Response, error) + {{with .DeprecationComment}}// + {{.}} + {{end}}{{$opid}}{{if .HasBody}}WithBody{{end}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*http.Response, error) {{range .Bodies}} {{if .IsSupportedByClient -}} - {{$opid}}{{.Suffix}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*http.Response, error) + {{with $deprecationComment}}{{.}} + {{end -}}{{$opid}}{{.Suffix}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*http.Response, error) {{end -}} {{end}}{{/* range .Bodies */}} {{end}}{{/* range . $opid := .OperationId */}} @@ -94,7 +98,8 @@ type ClientInterface interface { {{$pathParams := .PathParams -}} {{$opid := .OperationId -}} -func (c *{{ $clientTypeName }}) {{$opid}}{{if .HasBody}}WithBody{{end}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*http.Response, error) { +{{with .DeprecationComment}}{{.}} +{{end}}func (c *{{ $clientTypeName }}) {{$opid}}{{if .HasBody}}WithBody{{end}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}{{if .HasBody}}, contentType string, body io.Reader{{end}}, reqEditors... RequestEditorFn) (*http.Response, error) { req, err := New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(c.Server{{genParamNames .PathParams}}{{if $hasParams}}, params{{end}}{{if .HasBody}}, contentType, body{{end}}) if err != nil { return nil, err @@ -106,9 +111,11 @@ func (c *{{ $clientTypeName }}) {{$opid}}{{if .HasBody}}WithBody{{end}}(ctx cont return c.Client.Do(req) } +{{$deprecationComment := .DeprecationComment -}} {{range .Bodies}} {{if .IsSupportedByClient -}} -func (c *{{ $clientTypeName }}) {{$opid}}{{.Suffix}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*http.Response, error) { +{{with $deprecationComment}}{{.}} +{{end}}func (c *{{ $clientTypeName }}) {{$opid}}{{.Suffix}}(ctx context.Context{{genParamArgs $pathParams}}{{if $hasParams}}, params *{{$opid}}Params{{end}}, body {{$opid}}{{.NameTag}}RequestBody, reqEditors... RequestEditorFn) (*http.Response, error) { req, err := New{{$opid}}Request{{.Suffix}}(c.Server{{genParamNames $pathParams}}{{if $hasParams}}, params{{end}}, body) if err != nil { return nil, err diff --git a/pkg/codegen/templates/echo/echo-interface.tmpl b/pkg/codegen/templates/echo/echo-interface.tmpl index 683443270..2830ee3ed 100644 --- a/pkg/codegen/templates/echo/echo-interface.tmpl +++ b/pkg/codegen/templates/echo/echo-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(ctx echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(ctx echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error {{end}}{{end}} } diff --git a/pkg/codegen/templates/echo/v5/echo-interface.tmpl b/pkg/codegen/templates/echo/v5/echo-interface.tmpl index 6d5b874be..4386fd69b 100644 --- a/pkg/codegen/templates/echo/v5/echo-interface.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error {{end}}{{end}} } diff --git a/pkg/codegen/templates/fiber/fiber-interface.tmpl b/pkg/codegen/templates/fiber/fiber-interface.tmpl index 4459e8b0d..c8e2555ea 100644 --- a/pkg/codegen/templates/fiber/fiber-interface.tmpl +++ b/pkg/codegen/templates/fiber/fiber-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(c *fiber.Ctx{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(c *fiber.Ctx{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error {{end}}{{end}} } diff --git a/pkg/codegen/templates/gin/gin-interface.tmpl b/pkg/codegen/templates/gin/gin-interface.tmpl index dec255e71..55c6d8c13 100644 --- a/pkg/codegen/templates/gin/gin-interface.tmpl +++ b/pkg/codegen/templates/gin/gin-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(c *gin.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(c *gin.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) {{end}}{{end}} } diff --git a/pkg/codegen/templates/gorilla/gorilla-interface.tmpl b/pkg/codegen/templates/gorilla/gorilla-interface.tmpl index 04baa51e3..cadf05332 100644 --- a/pkg/codegen/templates/gorilla/gorilla-interface.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) {{end}}{{end}} } diff --git a/pkg/codegen/templates/iris/iris-interface.tmpl b/pkg/codegen/templates/iris/iris-interface.tmpl index 78f401ec2..49c98db10 100644 --- a/pkg/codegen/templates/iris/iris-interface.tmpl +++ b/pkg/codegen/templates/iris/iris-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(ctx iris.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(ctx iris.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) {{end}}{{end}} } diff --git a/pkg/codegen/templates/stdhttp/std-http-interface.tmpl b/pkg/codegen/templates/stdhttp/std-http-interface.tmpl index 04baa51e3..cadf05332 100644 --- a/pkg/codegen/templates/stdhttp/std-http-interface.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-interface.tmpl @@ -2,6 +2,8 @@ type ServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) +{{with .DeprecationComment}}// +{{.}} +{{end}}{{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) {{end}}{{end}} } diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index a88607a88..c07c25bf0 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -194,7 +194,9 @@ type StrictServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{$opid := .OperationId -}} +{{with .DeprecationComment}}// +{{.}} +{{end}}{{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) {{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 206cc88bd..ecdc74b37 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -32,7 +32,8 @@ {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.GoTypeDef}} + {{with .DeprecationComment}}{{.}} + {{end -}}{{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}} @@ -233,7 +234,9 @@ type StrictServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{$opid := .OperationId -}} +{{with .DeprecationComment}}// +{{.}} +{{end}}{{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) {{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index e48d7ab6d..06f8dfb59 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -195,7 +195,9 @@ type StrictServerInterface interface { {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) -{{$opid := .OperationId -}} +{{with .DeprecationComment}}// +{{.}} +{{end}}{{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) {{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-responses.tmpl b/pkg/codegen/templates/strict/strict-responses.tmpl index 5b4ee68c8..77cb520a4 100644 --- a/pkg/codegen/templates/strict/strict-responses.tmpl +++ b/pkg/codegen/templates/strict/strict-responses.tmpl @@ -4,7 +4,8 @@ {{if $hasHeaders -}} type {{$name}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.GoTypeDef}} + {{with .DeprecationComment}}{{.}} + {{end -}}{{.GoName}} {{.GoTypeDef}} {{end -}} } {{end -}} diff --git a/pkg/codegen/templates/typedef.tmpl b/pkg/codegen/templates/typedef.tmpl index be3112c0f..d06a1bd8e 100644 --- a/pkg/codegen/templates/typedef.tmpl +++ b/pkg/codegen/templates/typedef.tmpl @@ -1,4 +1,4 @@ {{range .Types}} -{{ if .Schema.Description }}{{ toGoComment .Schema.Description .TypeName }}{{ else }}// {{.TypeName}} defines model for {{.JsonName}}.{{ end }} +{{ .DocComment }} type {{.TypeName}} {{if .IsAlias }}={{end}} {{.Schema.TypeDecl}} {{end}} From 58ae5310e54f24360b705f1537cae39ee342ab46 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Sun, 14 Jun 2026 15:15:53 +0100 Subject: [PATCH 3/3] fixup! fix: deprecate **??** --- pkg/codegen/templates/strict/strict-fiber-interface.tmpl | 3 ++- pkg/codegen/templates/strict/strict-iris-interface.tmpl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index c07c25bf0..cdc7d8286 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -32,7 +32,8 @@ {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.GoTypeDef}} + {{with .DeprecationComment}}{{.}} + {{end -}}{{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}} diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 06f8dfb59..a0d334659 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -32,7 +32,8 @@ {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.GoTypeDef}} + {{with .DeprecationComment}}{{.}} + {{end -}}{{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}}