From 3a5f803e489c96de22c2b9155b8298b85e667ec8 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 2 Mar 2026 06:15:39 -0800 Subject: [PATCH 01/62] feat: multi-pass type name resolution (#2213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: multi-pass type name resolution I've been meaning to use this approach for a long time, because the attempts at avoiding type collisions via structure suffixes or prefixes work sporadically, at best. Conflict resolution is fundamentally a global problem, not a local problem when doing recursive traversal, so this PR splits the code generation into two parts. First, the OAPI document structure is traversed, and all the schemas that we generate are gathered up into a list of candidates, then we do global conflict resolution across the space of all schemas. This allows us to preserve the functionality of things affected by schema name - `$ref`, `required` properties, and so forth. This fixes issue #1474 (client response wrapper type colliding with a component schema of the same name and improves issue #200 handling (same name across schemas, parameters, responses, requestBodies, headers). The new system is gated behind the existing `resolve-type-name-collisions` output option. When disabled, behavior is unchanged, oapi-codegen exits with an error. This flag is default false, so there is no behavior change to oapi-codegen unless it's specified. All current test files regenerate without any differences. Added a comprehensive test which reproduces the scenarios in all the PR's and Issues below, and adds a few more, to make sure that references to renamed targets are also correct.. Key changes: - gather.go: walks entire spec collecting schemas with location metadata - resolve_names.go: assigns unique names via context suffix, per-schema disambiguation, and numeric fallback strategies - Component schemas are privileged and keep bare names on collision - Client response wrapper types now participate in collision detection - Removed ComponentType/DefinedComp from Schema struct - Removed FixDuplicateTypeNames and related functions from utils.go Obsoletes issues: - #1474 Schema name vs client wrapper (CreateChatCompletionResponse) - #1713 Schema name vs client wrapper (CreateBlueprintResponse) - #1450 Schema name vs client wrapper (DeleteBusinessResponse) - #2097 Path response type vs schema definition (Status) - #255 Endpoint path vs response type (QueryResponse) - #899 Duplicate types from response wrapper vs schema (AccessListResponse) - #1357 Schema vs operationId response (ListAssistantsResponse, OpenAI spec) - #254 Cross-section: requestBodies vs schemas (Pet) - #407 Cross-section: requestBodies vs schemas (myThing) - #1881 Cross-section: requestBodies with multiple content types Obsoletes PRs: - #292 Parameter structures params postfix (superseded by context suffix) - #1005 Fix generate equals structs (superseded by multi-pass resolution) Co-Authored-By: Claude Opus 4.6 EOF ) * Fix linter issues * fix: apply collision strategies in global phases to prevent oscillation When multiple content types map to the same short suffix (e.g., application/json, application/merge-patch+json, and application/json-patch+json all mapping to "JSON"), the per-group strategy cascade caused an infinite oscillation: context suffix appended "RequestBody", then content type suffix appended "JSON", then context suffix fired again because the name no longer ended in "RequestBody", ad infinitum. Fix by restructuring resolveCollisions to apply each strategy as a global phase: exhaust one strategy across ALL colliding groups (re-checking for new collisions after each pass) before advancing to the next strategy. This ensures numeric fallback is reached when earlier strategies cannot disambiguate. Also fix resolvedNameForComponent to accept an optional content type for exact matching, so each media type variant of a requestBody or response gets its own resolved name instead of all variants receiving whichever name the map iterator returns first. Adds Pattern H test case (TMF622 scenario from PR #2213): a component that exists in both schemas and requestBodies where the requestBody has 3 content types that all collapse to the "JSON" short name. Co-Authored-By: Claude Opus 4.6 * Regenerate files with new code * test: add Pattern I for inline response with x-go-type $ref properties Add test case from oapi-codegen-exp#14: an inline response object whose properties $ref component schemas with x-go-type: string. In the experimental rewrite (libopenapi), this caused duplicate type declarations because libopenapi copies extensions from $ref targets. V2 (kin-openapi) handles this correctly, but the test guards against future regressions. Co-Authored-By: Claude Opus 4.6 * fix: resolve type name mismatches for multi-content-type responses When a component response has multiple JSON content types (e.g., application/json, application/json-patch+json, application/merge-patch+json), three bugs produced uncompilable code: 1. Duplicate inline type declarations: GenerateGoSchema was called with a path of [operationId, responseName] (or [responseName] in the component phase), which doesn't include the content type. When multiple content types share oneOf schemas with inline elements, they produce identically-named AdditionalTypes. If the schemas differ, the result is conflicting declarations; if they're the same, duplicate declarations. Fix: include a mediaTypeToCamelCase(contentType) segment in the schema path when jsonCount > 1, giving each content type's inline types unique names. This is guarded by jsonCount > 1 for backward compatibility. 2. Undefined types in unmarshal code: GetResponseTypeDefinitions used RefPathToGoType to resolve $ref paths like #/components/responses/200Resource_Patch, but without content type context. resolvedNameForComponent fell into a non-deterministic prefix match, returning an arbitrary per-content-type base name that didn't match any defined type when mediaTypeToCamelCase was appended. Fix: add resolvedNameForRefPath helper that parses the $ref path and delegates to resolvedNameForComponent with the specific content type for exact matching. 3. Mismatched types in response struct fields: same root cause as bug 2 — the struct field types were derived from the same non-deterministic resolution path. Additionally, promote AdditionalTypes from GenerateTypesForResponses and GenerateTypesForRequestBodies to the top-level type list, matching the existing pattern in GenerateTypesForSchemas. Without this, inline types (e.g., oneOf union members, nested objects with additionalProperties) defined inside response/requestBody schemas were silently dropped from the output. Co-Authored-By: Claude Opus 4.6 * Address greptile's comment * fix: propagate user name overrides through codegen The collision resolver had two bugs when resolve-type-name-collisions was enabled: 1. x-go-name was ignored: generateCandidateName() never consulted the x-go-name extension, so schemas/responses/requestBodies/parameters/ headers with explicit Go name overrides would lose them during collision resolution. 2. Client wrapper names bypassed the name normalizer: generateCandidateName() used UppercaseFirstCharacter(operationID) instead of SchemaNameToTypeName(operationID), so configured normalizers (e.g. ToCamelCaseWithInitialisms) were not applied to client response wrapper type names. Changes: - Add GoNameOverride field to GatheredSchema, populated from x-go-name on the parent container (schema, response, requestBody, parameter, header) when the component is not a $ref - Add extractGoNameOverride() helper to read x-go-name from extensions - Add Pinned field to ResolvedName; pinned names are returned as-is from generateCandidateName() and skipped by all collision resolution strategies (context suffix, content type, status code, param index, numeric fallback) - Fix client wrapper candidate name to use SchemaNameToTypeName() - Add unit tests for GoNameOverride population and pinning behaviour - Add integration test patterns K/L/M (x-go-name on schema, response, and requestBody) and regenerate Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- configuration-schema.json | 2 +- internal/test/issues/issue-200/config.yaml | 7 - .../test/issues/issue-200/issue200.gen.go | 295 -- .../test/issues/issue-200/issue200_test.go | 63 - internal/test/issues/issue-200/spec.yaml | 96 - .../test/name_conflict_resolution/config.yaml | 8 + .../doc.go | 2 +- .../name_conflict_resolution.gen.go | 3000 +++++++++++++++++ .../name_conflict_resolution_test.go | 460 +++ .../test/name_conflict_resolution/spec.yaml | 607 ++++ pkg/codegen/codegen.go | 131 +- pkg/codegen/configuration.go | 6 +- pkg/codegen/extension.go | 10 +- pkg/codegen/gather.go | 331 ++ pkg/codegen/gather_test.go | 356 ++ pkg/codegen/operations.go | 30 +- pkg/codegen/resolve_names.go | 339 ++ pkg/codegen/resolve_names_test.go | 379 +++ pkg/codegen/schema.go | 24 +- pkg/codegen/template_helpers.go | 7 +- pkg/codegen/utils.go | 97 +- 21 files changed, 5664 insertions(+), 586 deletions(-) delete mode 100644 internal/test/issues/issue-200/config.yaml delete mode 100644 internal/test/issues/issue-200/issue200.gen.go delete mode 100644 internal/test/issues/issue-200/issue200_test.go delete mode 100644 internal/test/issues/issue-200/spec.yaml create mode 100644 internal/test/name_conflict_resolution/config.yaml rename internal/test/{issues/issue-200 => name_conflict_resolution}/doc.go (78%) create mode 100644 internal/test/name_conflict_resolution/name_conflict_resolution.gen.go create mode 100644 internal/test/name_conflict_resolution/name_conflict_resolution_test.go create mode 100644 internal/test/name_conflict_resolution/spec.yaml create mode 100644 pkg/codegen/gather.go create mode 100644 pkg/codegen/gather_test.go create mode 100644 pkg/codegen/resolve_names.go create mode 100644 pkg/codegen/resolve_names_test.go diff --git a/configuration-schema.json b/configuration-schema.json index 43694f9658..a81feefa3c 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -255,7 +255,7 @@ }, "resolve-type-name-collisions": { "type": "boolean", - "description": "When set to true, automatically renames types that collide across different OpenAPI component sections (schemas, parameters, requestBodies, responses, headers) by appending a suffix based on the component section (e.g., 'Parameter', 'Response', 'RequestBody'). Without this, the codegen will error on duplicate type names, requiring manual resolution via x-go-name.", + "description": "When set to true, automatically renames types that collide across different OpenAPI component sections (schemas, parameters, requestBodies, responses, headers) by appending a suffix based on the component section. Also detects collisions between component types and client response wrapper types. Without this, the codegen will error on duplicate type names, requiring manual resolution via x-go-name.", "default": false }, "type-mapping": { diff --git a/internal/test/issues/issue-200/config.yaml b/internal/test/issues/issue-200/config.yaml deleted file mode 100644 index d68804c987..0000000000 --- a/internal/test/issues/issue-200/config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# yaml-language-server: $schema=../../../../configuration-schema.json -package: issue200 -generate: - models: true -output: issue200.gen.go -output-options: - resolve-type-name-collisions: true diff --git a/internal/test/issues/issue-200/issue200.gen.go b/internal/test/issues/issue-200/issue200.gen.go deleted file mode 100644 index 530c042c7a..0000000000 --- a/internal/test/issues/issue-200/issue200.gen.go +++ /dev/null @@ -1,295 +0,0 @@ -// Package issue200 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 issue200 - -import ( - "encoding/json" - "fmt" -) - -// Bar defines model for Bar. -type Bar struct { - Value *string `json:"value,omitempty"` -} - -// Bar2 defines model for Bar2. -type Bar2 struct { - Value *float32 `json:"value,omitempty"` -} - -// BarParam defines model for BarParam. -type BarParam = []int - -// BarParam2 defines model for BarParam2. -type BarParam2 = []int - -// BarParameter defines model for Bar. -type BarParameter = string - -// BarResponse defines model for Bar. -type BarResponse struct { - Pagination *Bar_Pagination `json:"pagination,omitempty"` - Value1 *Bar `json:"value1,omitempty"` - Value2 *Bar2 `json:"value2,omitempty"` - Value3 *BarParam `json:"value3,omitempty"` - Value4 *BarParam2 `json:"value4,omitempty"` -} - -// Bar_Pagination defines model for Bar.Pagination. -type Bar_Pagination struct { - Page *int `json:"page,omitempty"` - TotalPages *int `json:"totalPages,omitempty"` - AdditionalProperties map[string]string `json:"-"` -} - -// BarRequestBody defines model for Bar. -type BarRequestBody struct { - Metadata *Bar_Metadata `json:"metadata,omitempty"` - Value *int `json:"value,omitempty"` -} - -// Bar_Metadata defines model for Bar.Metadata. -type Bar_Metadata struct { - Key *string `json:"key,omitempty"` - AdditionalProperties map[string]string `json:"-"` -} - -// PostFooJSONBody defines parameters for PostFoo. -type PostFooJSONBody struct { - Metadata *PostFooJSONBody_Metadata `json:"metadata,omitempty"` - Value *int `json:"value,omitempty"` -} - -// PostFooParams defines parameters for PostFoo. -type PostFooParams struct { - Bar *Bar `form:"Bar,omitempty" json:"Bar,omitempty"` -} - -// PostFooJSONBody_Metadata defines parameters for PostFoo. -type PostFooJSONBody_Metadata struct { - Key *string `json:"key,omitempty"` - AdditionalProperties map[string]string `json:"-"` -} - -// PostFooJSONRequestBody defines body for PostFoo for application/json ContentType. -type PostFooJSONRequestBody PostFooJSONBody - -// Getter for additional properties for PostFooJSONBody_Metadata. Returns the specified -// element and whether it was found -func (a PostFooJSONBody_Metadata) Get(fieldName string) (value string, found bool) { - if a.AdditionalProperties != nil { - value, found = a.AdditionalProperties[fieldName] - } - return -} - -// Setter for additional properties for PostFooJSONBody_Metadata -func (a *PostFooJSONBody_Metadata) Set(fieldName string, value string) { - if a.AdditionalProperties == nil { - a.AdditionalProperties = make(map[string]string) - } - a.AdditionalProperties[fieldName] = value -} - -// Override default JSON handling for PostFooJSONBody_Metadata to handle AdditionalProperties -func (a *PostFooJSONBody_Metadata) UnmarshalJSON(b []byte) error { - object := make(map[string]json.RawMessage) - err := json.Unmarshal(b, &object) - if err != nil { - return err - } - - if raw, found := object["key"]; found { - err = json.Unmarshal(raw, &a.Key) - if err != nil { - return fmt.Errorf("error reading 'key': %w", err) - } - delete(object, "key") - } - - if len(object) != 0 { - a.AdditionalProperties = make(map[string]string) - for fieldName, fieldBuf := range object { - var fieldVal string - err := json.Unmarshal(fieldBuf, &fieldVal) - if err != nil { - return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) - } - a.AdditionalProperties[fieldName] = fieldVal - } - } - return nil -} - -// Override default JSON handling for PostFooJSONBody_Metadata to handle AdditionalProperties -func (a PostFooJSONBody_Metadata) MarshalJSON() ([]byte, error) { - var err error - object := make(map[string]json.RawMessage) - - if a.Key != nil { - object["key"], err = json.Marshal(a.Key) - if err != nil { - return nil, fmt.Errorf("error marshaling 'key': %w", err) - } - } - - for fieldName, field := range a.AdditionalProperties { - object[fieldName], err = json.Marshal(field) - if err != nil { - return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) - } - } - return json.Marshal(object) -} - -// Getter for additional properties for Bar_Pagination. Returns the specified -// element and whether it was found -func (a Bar_Pagination) Get(fieldName string) (value string, found bool) { - if a.AdditionalProperties != nil { - value, found = a.AdditionalProperties[fieldName] - } - return -} - -// Setter for additional properties for Bar_Pagination -func (a *Bar_Pagination) Set(fieldName string, value string) { - if a.AdditionalProperties == nil { - a.AdditionalProperties = make(map[string]string) - } - a.AdditionalProperties[fieldName] = value -} - -// Override default JSON handling for Bar_Pagination to handle AdditionalProperties -func (a *Bar_Pagination) UnmarshalJSON(b []byte) error { - object := make(map[string]json.RawMessage) - err := json.Unmarshal(b, &object) - if err != nil { - return err - } - - if raw, found := object["page"]; found { - err = json.Unmarshal(raw, &a.Page) - if err != nil { - return fmt.Errorf("error reading 'page': %w", err) - } - delete(object, "page") - } - - if raw, found := object["totalPages"]; found { - err = json.Unmarshal(raw, &a.TotalPages) - if err != nil { - return fmt.Errorf("error reading 'totalPages': %w", err) - } - delete(object, "totalPages") - } - - if len(object) != 0 { - a.AdditionalProperties = make(map[string]string) - for fieldName, fieldBuf := range object { - var fieldVal string - err := json.Unmarshal(fieldBuf, &fieldVal) - if err != nil { - return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) - } - a.AdditionalProperties[fieldName] = fieldVal - } - } - return nil -} - -// Override default JSON handling for Bar_Pagination to handle AdditionalProperties -func (a Bar_Pagination) MarshalJSON() ([]byte, error) { - var err error - object := make(map[string]json.RawMessage) - - if a.Page != nil { - object["page"], err = json.Marshal(a.Page) - if err != nil { - return nil, fmt.Errorf("error marshaling 'page': %w", err) - } - } - - if a.TotalPages != nil { - object["totalPages"], err = json.Marshal(a.TotalPages) - if err != nil { - return nil, fmt.Errorf("error marshaling 'totalPages': %w", err) - } - } - - for fieldName, field := range a.AdditionalProperties { - object[fieldName], err = json.Marshal(field) - if err != nil { - return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) - } - } - return json.Marshal(object) -} - -// Getter for additional properties for Bar_Metadata. Returns the specified -// element and whether it was found -func (a Bar_Metadata) Get(fieldName string) (value string, found bool) { - if a.AdditionalProperties != nil { - value, found = a.AdditionalProperties[fieldName] - } - return -} - -// Setter for additional properties for Bar_Metadata -func (a *Bar_Metadata) Set(fieldName string, value string) { - if a.AdditionalProperties == nil { - a.AdditionalProperties = make(map[string]string) - } - a.AdditionalProperties[fieldName] = value -} - -// Override default JSON handling for Bar_Metadata to handle AdditionalProperties -func (a *Bar_Metadata) UnmarshalJSON(b []byte) error { - object := make(map[string]json.RawMessage) - err := json.Unmarshal(b, &object) - if err != nil { - return err - } - - if raw, found := object["key"]; found { - err = json.Unmarshal(raw, &a.Key) - if err != nil { - return fmt.Errorf("error reading 'key': %w", err) - } - delete(object, "key") - } - - if len(object) != 0 { - a.AdditionalProperties = make(map[string]string) - for fieldName, fieldBuf := range object { - var fieldVal string - err := json.Unmarshal(fieldBuf, &fieldVal) - if err != nil { - return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) - } - a.AdditionalProperties[fieldName] = fieldVal - } - } - return nil -} - -// Override default JSON handling for Bar_Metadata to handle AdditionalProperties -func (a Bar_Metadata) MarshalJSON() ([]byte, error) { - var err error - object := make(map[string]json.RawMessage) - - if a.Key != nil { - object["key"], err = json.Marshal(a.Key) - if err != nil { - return nil, fmt.Errorf("error marshaling 'key': %w", err) - } - } - - for fieldName, field := range a.AdditionalProperties { - object[fieldName], err = json.Marshal(field) - if err != nil { - return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) - } - } - return json.Marshal(object) -} diff --git a/internal/test/issues/issue-200/issue200_test.go b/internal/test/issues/issue-200/issue200_test.go deleted file mode 100644 index 96fdb62e8b..0000000000 --- a/internal/test/issues/issue-200/issue200_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package issue200 - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -// TestDuplicateTypeNamesCompile verifies that when the same name "Bar" is used -// across components/schemas, components/parameters, components/responses, -// components/requestBodies, and components/headers, the codegen produces -// distinct, compilable types with component-based suffixes. -// -// If the auto-rename logic breaks, this test will fail to compile. -func TestDuplicateTypeNamesCompile(t *testing.T) { - // Schema type: Bar (no suffix, first definition wins) - _ = Bar{Value: ptr("hello")} - - // Schema types with unique names (no collision) - _ = Bar2{Value: ptr(float32(1.0))} - _ = BarParam([]int{1, 2, 3}) - _ = BarParam2([]int{4, 5, 6}) - - // Parameter type: BarParameter (was "Bar" in components/parameters) - _ = BarParameter("query-value") - - // Response type: BarResponse (was "Bar" in components/responses) - _ = BarResponse{ - Value1: &Bar{Value: ptr("v1")}, - Value2: &Bar2{Value: ptr(float32(2.0))}, - Value3: &BarParam{1}, - Value4: &BarParam2{2}, - } - - // RequestBody type: BarRequestBody (was "Bar" in components/requestBodies) - _ = BarRequestBody{Value: ptr(42)} - - // Inline nested object with additionalProperties inside a response - // must produce a named AdditionalType (not get silently dropped). - _ = Bar_Pagination{ - Page: ptr(1), - TotalPages: ptr(10), - AdditionalProperties: map[string]string{"cursor": "abc"}, - } - - // Inline nested object with additionalProperties inside a requestBody - // must produce a named AdditionalType (not get silently dropped). - _ = Bar_Metadata{ - Key: ptr("k"), - AdditionalProperties: map[string]string{"extra": "val"}, - } - - // Operation-derived types - _ = PostFooParams{Bar: &Bar{}} - _ = PostFooJSONBody{Value: ptr(99)} - _ = PostFooJSONRequestBody{Value: ptr(100)} - - assert.True(t, true, "all duplicate-named types resolved and compiled") -} - -func ptr[T any](v T) *T { - return &v -} diff --git a/internal/test/issues/issue-200/spec.yaml b/internal/test/issues/issue-200/spec.yaml deleted file mode 100644 index 2a68f71694..0000000000 --- a/internal/test/issues/issue-200/spec.yaml +++ /dev/null @@ -1,96 +0,0 @@ -openapi: 3.0.1 - -info: - title: "Duplicate type names test" - version: 0.0.0 - -paths: - /foo: - post: - operationId: postFoo - parameters: - - $ref: '#/components/parameters/Bar' - requestBody: - $ref: '#/components/requestBodies/Bar' - responses: - 200: - $ref: '#/components/responses/Bar' - -components: - schemas: - Bar: - type: object - properties: - value: - type: string - Bar2: - type: object - properties: - value: - type: number - BarParam: - type: array - items: - type: integer - BarParam2: - type: array - items: - type: integer - - headers: - Bar: - schema: - type: boolean - - parameters: - Bar: - name: Bar - in: query - schema: - type: string - - requestBodies: - Bar: - content: - application/json: - schema: - type: object - properties: - value: - type: integer - metadata: - type: object - properties: - key: - type: string - additionalProperties: - type: string - - responses: - Bar: - description: Bar response - headers: - X-Bar: - $ref: '#/components/headers/Bar' - content: - application/json: - schema: - type: object - properties: - value1: - $ref: '#/components/schemas/Bar' - value2: - $ref: '#/components/schemas/Bar2' - value3: - $ref: '#/components/schemas/BarParam' - value4: - $ref: '#/components/schemas/BarParam2' - pagination: - type: object - properties: - page: - type: integer - totalPages: - type: integer - additionalProperties: - type: string diff --git a/internal/test/name_conflict_resolution/config.yaml b/internal/test/name_conflict_resolution/config.yaml new file mode 100644 index 0000000000..6e173b0a4e --- /dev/null +++ b/internal/test/name_conflict_resolution/config.yaml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=../../../configuration-schema.json +package: nameconflictresolution +generate: + models: true + client: true +output: name_conflict_resolution.gen.go +output-options: + resolve-type-name-collisions: true diff --git a/internal/test/issues/issue-200/doc.go b/internal/test/name_conflict_resolution/doc.go similarity index 78% rename from internal/test/issues/issue-200/doc.go rename to internal/test/name_conflict_resolution/doc.go index 733ebfce17..4d577571ef 100644 --- a/internal/test/issues/issue-200/doc.go +++ b/internal/test/name_conflict_resolution/doc.go @@ -1,3 +1,3 @@ -package issue200 +package nameconflictresolution //go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go new file mode 100644 index 0000000000..068f8e6d4a --- /dev/null +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -0,0 +1,3000 @@ +// Package nameconflictresolution 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 nameconflictresolution + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// Bar defines model for Bar. +type Bar struct { + Value *string `json:"value,omitempty"` +} + +// Bar2 defines model for Bar2. +type Bar2 struct { + Value *float32 `json:"value,omitempty"` +} + +// CreateItemResponse defines model for CreateItemResponse. +type CreateItemResponse struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +// GetStatusResponse defines model for GetStatusResponse. +type GetStatusResponse struct { + Status *string `json:"status,omitempty"` + Timestamp *string `json:"timestamp,omitempty"` +} + +// JsonPatch defines model for JsonPatch. +type JsonPatch = []struct { + Op *string `json:"op,omitempty"` + Path *string `json:"path,omitempty"` +} + +// ListItemsResponse defines model for ListItemsResponse. +type ListItemsResponse = string + +// Metadata defines model for Metadata. +type Metadata = string + +// Order defines model for Order. +type Order struct { + Id *string `json:"id,omitempty"` + Product *string `json:"product,omitempty"` +} + +// Outcome defines model for Outcome. +type Outcome struct { + Value *string `json:"value,omitempty"` +} + +// Payload defines model for Payload. +type Payload struct { + Content *string `json:"content,omitempty"` +} + +// Pet defines model for Pet. +type Pet struct { + Id *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +// QueryResponse defines model for QueryResponse. +type QueryResponse struct { + Results *[]string `json:"results,omitempty"` +} + +// Qux defines model for Qux. +type Qux = CustomQux + +// CustomQux defines model for . +type CustomQux struct { + Label *string `json:"label,omitempty"` +} + +// SpecialName defines model for Renamer. +type SpecialName struct { + Label *string `json:"label,omitempty"` +} + +// Resource defines model for Resource. +type Resource struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` +} + +// ResourceMVO defines model for Resource_MVO. +type ResourceMVO struct { + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` +} + +// Widget defines model for Widget. +type Widget = string + +// Zap defines model for Zap. +type Zap = string + +// BarParameter defines model for Bar. +type BarParameter = string + +// N200ResourcePatchResponseJSONApplicationJSON defines model for 200Resource_Patch. +type N200ResourcePatchResponseJSONApplicationJSON = Resource + +// N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON defines model for 200Resource_Patch. +type N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON struct { + union json.RawMessage +} + +// N200ResourcePatchApplicationJSONPatchPlusJSON1 defines model for . +type N200ResourcePatchApplicationJSONPatchPlusJSON1 = []Resource + +// N200ResourcePatchApplicationJSONPatchPlusJSON2 defines model for . +type N200ResourcePatchApplicationJSONPatchPlusJSON2 = string + +// N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON defines model for 200Resource_Patch. +type N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON struct { + union json.RawMessage +} + +// N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 defines model for . +type N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 = []Resource + +// N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 defines model for . +type N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 = string + +// N200ResourcePatchResponseJSON4ApplicationMergePatchPlusJSON defines model for 200Resource_Patch. +type N200ResourcePatchResponseJSON4ApplicationMergePatchPlusJSON = Resource + +// BarResponse defines model for Bar. +type BarResponse struct { + Value1 *Bar `json:"value1,omitempty"` + Value2 *Bar2 `json:"value2,omitempty"` +} + +// OutcomeResult defines model for Outcome. +type OutcomeResult struct { + Result *string `json:"result,omitempty"` +} + +// QuxResponse defines model for Qux. +type QuxResponse struct { + Data *string `json:"data,omitempty"` +} + +// Renamer defines model for Renamer. +type Renamer struct { + Data *string `json:"data,omitempty"` +} + +// ZapResponse defines model for Zap. +type ZapResponse struct { + Result *string `json:"result,omitempty"` +} + +// BarRequestBody defines model for Bar. +type BarRequestBody struct { + Value *int `json:"value,omitempty"` +} + +// OrderRequestBodyJSON defines model for Order. +type OrderRequestBodyJSON struct { + Id *string `json:"id,omitempty"` + Product *string `json:"product,omitempty"` +} + +// OrderRequestBodyJSON2 defines model for Order. +type OrderRequestBodyJSON2 = []struct { + Op *string `json:"op,omitempty"` + Path *string `json:"path,omitempty"` + Value *string `json:"value,omitempty"` +} + +// OrderRequestBodyJSON3 defines model for Order. +type OrderRequestBodyJSON3 struct { + Product *string `json:"product,omitempty"` +} + +// PayloadBody defines model for Payload. +type PayloadBody struct { + Data *string `json:"data,omitempty"` +} + +// PetRequestBody defines model for Pet. +type PetRequestBody struct { + Name *string `json:"name,omitempty"` + Species *string `json:"species,omitempty"` +} + +// ResourceMVORequestBodyJSON defines model for Resource_MVO. +type ResourceMVORequestBodyJSON = ResourceMVO + +// ResourceMVORequestBodyJSON2 defines model for Resource_MVO. +type ResourceMVORequestBodyJSON2 = JsonPatch + +// ResourceMVORequestBodyJSON3 defines model for Resource_MVO. +type ResourceMVORequestBodyJSON3 = ResourceMVO + +// PostFooJSONBody defines parameters for PostFoo. +type PostFooJSONBody struct { + Value *int `json:"value,omitempty"` +} + +// PostFooParams defines parameters for PostFoo. +type PostFooParams struct { + Bar *BarParameter `form:"bar,omitempty" json:"bar,omitempty"` +} + +// CreateItemJSONBody defines parameters for CreateItem. +type CreateItemJSONBody struct { + Name *string `json:"name,omitempty"` +} + +// CreateOrderJSONBody defines parameters for CreateOrder. +type CreateOrderJSONBody struct { + Id *string `json:"id,omitempty"` + Product *string `json:"product,omitempty"` +} + +// CreateOrderApplicationJSONPatchPlusJSONBody defines parameters for CreateOrder. +type CreateOrderApplicationJSONPatchPlusJSONBody = []struct { + Op *string `json:"op,omitempty"` + Path *string `json:"path,omitempty"` + Value *string `json:"value,omitempty"` +} + +// CreateOrderApplicationMergePatchPlusJSONBody defines parameters for CreateOrder. +type CreateOrderApplicationMergePatchPlusJSONBody struct { + Product *string `json:"product,omitempty"` +} + +// SendPayloadJSONBody defines parameters for SendPayload. +type SendPayloadJSONBody struct { + Data *string `json:"data,omitempty"` +} + +// CreatePetJSONBody defines parameters for CreatePet. +type CreatePetJSONBody struct { + Name *string `json:"name,omitempty"` + Species *string `json:"species,omitempty"` +} + +// QueryJSONBody defines parameters for Query. +type QueryJSONBody struct { + Q *string `json:"q,omitempty"` +} + +// PostFooJSONRequestBody defines body for PostFoo for application/json ContentType. +type PostFooJSONRequestBody PostFooJSONBody + +// CreateItemJSONRequestBody defines body for CreateItem for application/json ContentType. +type CreateItemJSONRequestBody CreateItemJSONBody + +// CreateOrderJSONRequestBody defines body for CreateOrder for application/json ContentType. +type CreateOrderJSONRequestBody CreateOrderJSONBody + +// CreateOrderApplicationJSONPatchPlusJSONRequestBody defines body for CreateOrder for application/json-patch+json ContentType. +type CreateOrderApplicationJSONPatchPlusJSONRequestBody = CreateOrderApplicationJSONPatchPlusJSONBody + +// CreateOrderApplicationMergePatchPlusJSONRequestBody defines body for CreateOrder for application/merge-patch+json ContentType. +type CreateOrderApplicationMergePatchPlusJSONRequestBody CreateOrderApplicationMergePatchPlusJSONBody + +// PostOutcomeJSONRequestBody defines body for PostOutcome for application/json ContentType. +type PostOutcomeJSONRequestBody = Outcome + +// SendPayloadJSONRequestBody defines body for SendPayload for application/json ContentType. +type SendPayloadJSONRequestBody SendPayloadJSONBody + +// CreatePetJSONRequestBody defines body for CreatePet for application/json ContentType. +type CreatePetJSONRequestBody CreatePetJSONBody + +// QueryJSONRequestBody defines body for Query for application/json ContentType. +type QueryJSONRequestBody QueryJSONBody + +// PostQuxJSONRequestBody defines body for PostQux for application/json ContentType. +type PostQuxJSONRequestBody = Qux + +// PostRenamedSchemaJSONRequestBody defines body for PostRenamedSchema for application/json ContentType. +type PostRenamedSchemaJSONRequestBody = SpecialName + +// PatchResourceJSONRequestBody defines body for PatchResource for application/json ContentType. +type PatchResourceJSONRequestBody = ResourceMVO + +// PatchResourceApplicationJSONPatchPlusJSONRequestBody defines body for PatchResource for application/json-patch+json ContentType. +type PatchResourceApplicationJSONPatchPlusJSONRequestBody = JsonPatch + +// PatchResourceApplicationMergePatchPlusJSONRequestBody defines body for PatchResource for application/merge-patch+json ContentType. +type PatchResourceApplicationMergePatchPlusJSONRequestBody = ResourceMVO + +// PostZapJSONRequestBody defines body for PostZap for application/json ContentType. +type PostZapJSONRequestBody = Zap + +// AsResource returns the union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as a Resource +func (t N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) AsResource() (Resource, error) { + var body Resource + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromResource overwrites any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as the provided Resource +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) FromResource(v Resource) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeResource performs a merge with any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON, using the provided Resource +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) MergeResource(v Resource) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsN200ResourcePatchApplicationJSONPatchPlusJSON1 returns the union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as a N200ResourcePatchApplicationJSONPatchPlusJSON1 +func (t N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) AsN200ResourcePatchApplicationJSONPatchPlusJSON1() (N200ResourcePatchApplicationJSONPatchPlusJSON1, error) { + var body N200ResourcePatchApplicationJSONPatchPlusJSON1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromN200ResourcePatchApplicationJSONPatchPlusJSON1 overwrites any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as the provided N200ResourcePatchApplicationJSONPatchPlusJSON1 +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) FromN200ResourcePatchApplicationJSONPatchPlusJSON1(v N200ResourcePatchApplicationJSONPatchPlusJSON1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeN200ResourcePatchApplicationJSONPatchPlusJSON1 performs a merge with any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON, using the provided N200ResourcePatchApplicationJSONPatchPlusJSON1 +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) MergeN200ResourcePatchApplicationJSONPatchPlusJSON1(v N200ResourcePatchApplicationJSONPatchPlusJSON1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsN200ResourcePatchApplicationJSONPatchPlusJSON2 returns the union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as a N200ResourcePatchApplicationJSONPatchPlusJSON2 +func (t N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) AsN200ResourcePatchApplicationJSONPatchPlusJSON2() (N200ResourcePatchApplicationJSONPatchPlusJSON2, error) { + var body N200ResourcePatchApplicationJSONPatchPlusJSON2 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromN200ResourcePatchApplicationJSONPatchPlusJSON2 overwrites any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON as the provided N200ResourcePatchApplicationJSONPatchPlusJSON2 +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) FromN200ResourcePatchApplicationJSONPatchPlusJSON2(v N200ResourcePatchApplicationJSONPatchPlusJSON2) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeN200ResourcePatchApplicationJSONPatchPlusJSON2 performs a merge with any union data inside the N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON, using the provided N200ResourcePatchApplicationJSONPatchPlusJSON2 +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) MergeN200ResourcePatchApplicationJSONPatchPlusJSON2(v N200ResourcePatchApplicationJSONPatchPlusJSON2) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsResource returns the union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as a Resource +func (t N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) AsResource() (Resource, error) { + var body Resource + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromResource overwrites any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as the provided Resource +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) FromResource(v Resource) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeResource performs a merge with any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON, using the provided Resource +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) MergeResource(v Resource) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsN200ResourcePatchApplicationJSONPatchQueryPlusJSON1 returns the union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as a N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 +func (t N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) AsN200ResourcePatchApplicationJSONPatchQueryPlusJSON1() (N200ResourcePatchApplicationJSONPatchQueryPlusJSON1, error) { + var body N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromN200ResourcePatchApplicationJSONPatchQueryPlusJSON1 overwrites any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as the provided N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) FromN200ResourcePatchApplicationJSONPatchQueryPlusJSON1(v N200ResourcePatchApplicationJSONPatchQueryPlusJSON1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeN200ResourcePatchApplicationJSONPatchQueryPlusJSON1 performs a merge with any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON, using the provided N200ResourcePatchApplicationJSONPatchQueryPlusJSON1 +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) MergeN200ResourcePatchApplicationJSONPatchQueryPlusJSON1(v N200ResourcePatchApplicationJSONPatchQueryPlusJSON1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsN200ResourcePatchApplicationJSONPatchQueryPlusJSON2 returns the union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as a N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 +func (t N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) AsN200ResourcePatchApplicationJSONPatchQueryPlusJSON2() (N200ResourcePatchApplicationJSONPatchQueryPlusJSON2, error) { + var body N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromN200ResourcePatchApplicationJSONPatchQueryPlusJSON2 overwrites any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON as the provided N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) FromN200ResourcePatchApplicationJSONPatchQueryPlusJSON2(v N200ResourcePatchApplicationJSONPatchQueryPlusJSON2) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeN200ResourcePatchApplicationJSONPatchQueryPlusJSON2 performs a merge with any union data inside the N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON, using the provided N200ResourcePatchApplicationJSONPatchQueryPlusJSON2 +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) MergeN200ResourcePatchApplicationJSONPatchQueryPlusJSON2(v N200ResourcePatchApplicationJSONPatchQueryPlusJSON2) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // ListEntities request + ListEntities(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostFooWithBody request with any body + PostFooWithBody(ctx context.Context, params *PostFooParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostFoo(ctx context.Context, params *PostFooParams, body PostFooJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ListItems request + ListItems(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateItemWithBody request with any body + CreateItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateItem(ctx context.Context, body CreateItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateOrderWithBody request with any body + CreateOrderWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateOrder(ctx context.Context, body CreateOrderJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateOrderWithApplicationJSONPatchPlusJSONBody(ctx context.Context, body CreateOrderApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateOrderWithApplicationMergePatchPlusJSONBody(ctx context.Context, body CreateOrderApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetOutcome request + GetOutcome(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostOutcomeWithBody request with any body + PostOutcomeWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostOutcome(ctx context.Context, body PostOutcomeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // SendPayloadWithBody request with any body + SendPayloadWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + SendPayload(ctx context.Context, body SendPayloadJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreatePetWithBody request with any body + CreatePetWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreatePet(ctx context.Context, body CreatePetJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // QueryWithBody request with any body + QueryWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + Query(ctx context.Context, body QueryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetQux request + GetQux(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostQuxWithBody request with any body + PostQuxWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostQux(ctx context.Context, body PostQuxJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetRenamedSchema request + GetRenamedSchema(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostRenamedSchemaWithBody request with any body + PostRenamedSchemaWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostRenamedSchema(ctx context.Context, body PostRenamedSchemaJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PatchResourceWithBody request with any body + PatchResourceWithBody(ctx context.Context, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PatchResource(ctx context.Context, id string, body PatchResourceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + PatchResourceWithApplicationJSONPatchPlusJSONBody(ctx context.Context, id string, body PatchResourceApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + PatchResourceWithApplicationMergePatchPlusJSONBody(ctx context.Context, id string, body PatchResourceApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetStatus request + GetStatus(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetZap request + GetZap(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostZapWithBody request with any body + PostZapWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostZap(ctx context.Context, body PostZapJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) ListEntities(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListEntitiesRequest(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 *Client) PostFooWithBody(ctx context.Context, params *PostFooParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostFooRequestWithBody(c.Server, params, 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 *Client) PostFoo(ctx context.Context, params *PostFooParams, body PostFooJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostFooRequest(c.Server, params, 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 *Client) ListItems(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListItemsRequest(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 *Client) CreateItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateItemRequestWithBody(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 *Client) CreateItem(ctx context.Context, body CreateItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateItemRequest(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 *Client) CreateOrderWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateOrderRequestWithBody(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 *Client) CreateOrder(ctx context.Context, body CreateOrderJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateOrderRequest(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 *Client) CreateOrderWithApplicationJSONPatchPlusJSONBody(ctx context.Context, body CreateOrderApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateOrderRequestWithApplicationJSONPatchPlusJSONBody(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 *Client) CreateOrderWithApplicationMergePatchPlusJSONBody(ctx context.Context, body CreateOrderApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateOrderRequestWithApplicationMergePatchPlusJSONBody(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 *Client) GetOutcome(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetOutcomeRequest(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 *Client) PostOutcomeWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostOutcomeRequestWithBody(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 *Client) PostOutcome(ctx context.Context, body PostOutcomeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostOutcomeRequest(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 *Client) SendPayloadWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSendPayloadRequestWithBody(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 *Client) SendPayload(ctx context.Context, body SendPayloadJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSendPayloadRequest(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 *Client) CreatePetWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreatePetRequestWithBody(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 *Client) CreatePet(ctx context.Context, body CreatePetJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreatePetRequest(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 *Client) QueryWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewQueryRequestWithBody(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 *Client) Query(ctx context.Context, body QueryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewQueryRequest(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 *Client) GetQux(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetQuxRequest(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 *Client) PostQuxWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostQuxRequestWithBody(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 *Client) PostQux(ctx context.Context, body PostQuxJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostQuxRequest(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 *Client) GetRenamedSchema(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetRenamedSchemaRequest(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 *Client) PostRenamedSchemaWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostRenamedSchemaRequestWithBody(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 *Client) PostRenamedSchema(ctx context.Context, body PostRenamedSchemaJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostRenamedSchemaRequest(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 *Client) PatchResourceWithBody(ctx context.Context, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchResourceRequestWithBody(c.Server, id, 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 *Client) PatchResource(ctx context.Context, id string, body PatchResourceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchResourceRequest(c.Server, id, 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 *Client) PatchResourceWithApplicationJSONPatchPlusJSONBody(ctx context.Context, id string, body PatchResourceApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchResourceRequestWithApplicationJSONPatchPlusJSONBody(c.Server, id, 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 *Client) PatchResourceWithApplicationMergePatchPlusJSONBody(ctx context.Context, id string, body PatchResourceApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchResourceRequestWithApplicationMergePatchPlusJSONBody(c.Server, id, 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 *Client) GetStatus(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetStatusRequest(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 *Client) GetZap(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetZapRequest(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 *Client) PostZapWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostZapRequestWithBody(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 *Client) PostZap(ctx context.Context, body PostZapJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostZapRequest(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) +} + +// NewListEntitiesRequest generates requests for ListEntities +func NewListEntitiesRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/entities") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostFooRequest calls the generic PostFoo builder with application/json body +func NewPostFooRequest(server string, params *PostFooParams, body PostFooJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostFooRequestWithBody(server, params, "application/json", bodyReader) +} + +// NewPostFooRequestWithBody generates requests for PostFoo with any type of body +func NewPostFooRequestWithBody(server string, params *PostFooParams, 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("/foo") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Bar != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "bar", *params.Bar, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewListItemsRequest generates requests for ListItems +func NewListItemsRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/items") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateItemRequest calls the generic CreateItem builder with application/json body +func NewCreateItemRequest(server string, body CreateItemJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateItemRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreateItemRequestWithBody generates requests for CreateItem with any type of body +func NewCreateItemRequestWithBody(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("/items") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewCreateOrderRequest calls the generic CreateOrder builder with application/json body +func NewCreateOrderRequest(server string, body CreateOrderJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateOrderRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreateOrderRequestWithApplicationJSONPatchPlusJSONBody calls the generic CreateOrder builder with application/json-patch+json body +func NewCreateOrderRequestWithApplicationJSONPatchPlusJSONBody(server string, body CreateOrderApplicationJSONPatchPlusJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateOrderRequestWithBody(server, "application/json-patch+json", bodyReader) +} + +// NewCreateOrderRequestWithApplicationMergePatchPlusJSONBody calls the generic CreateOrder builder with application/merge-patch+json body +func NewCreateOrderRequestWithApplicationMergePatchPlusJSONBody(server string, body CreateOrderApplicationMergePatchPlusJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateOrderRequestWithBody(server, "application/merge-patch+json", bodyReader) +} + +// NewCreateOrderRequestWithBody generates requests for CreateOrder with any type of body +func NewCreateOrderRequestWithBody(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("/orders") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetOutcomeRequest generates requests for GetOutcome +func NewGetOutcomeRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/outcome") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostOutcomeRequest calls the generic PostOutcome builder with application/json body +func NewPostOutcomeRequest(server string, body PostOutcomeJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostOutcomeRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostOutcomeRequestWithBody generates requests for PostOutcome with any type of body +func NewPostOutcomeRequestWithBody(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("/outcome") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewSendPayloadRequest calls the generic SendPayload builder with application/json body +func NewSendPayloadRequest(server string, body SendPayloadJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewSendPayloadRequestWithBody(server, "application/json", bodyReader) +} + +// NewSendPayloadRequestWithBody generates requests for SendPayload with any type of body +func NewSendPayloadRequestWithBody(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("/payload") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewCreatePetRequest calls the generic CreatePet builder with application/json body +func NewCreatePetRequest(server string, body CreatePetJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreatePetRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreatePetRequestWithBody generates requests for CreatePet with any type of body +func NewCreatePetRequestWithBody(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("/pets") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewQueryRequest calls the generic Query builder with application/json body +func NewQueryRequest(server string, body QueryJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewQueryRequestWithBody(server, "application/json", bodyReader) +} + +// NewQueryRequestWithBody generates requests for Query with any type of body +func NewQueryRequestWithBody(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("/query") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetQuxRequest generates requests for GetQux +func NewGetQuxRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/qux") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostQuxRequest calls the generic PostQux builder with application/json body +func NewPostQuxRequest(server string, body PostQuxJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostQuxRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostQuxRequestWithBody generates requests for PostQux with any type of body +func NewPostQuxRequestWithBody(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("/qux") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetRenamedSchemaRequest generates requests for GetRenamedSchema +func NewGetRenamedSchemaRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/renamed-schema") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostRenamedSchemaRequest calls the generic PostRenamedSchema builder with application/json body +func NewPostRenamedSchemaRequest(server string, body PostRenamedSchemaJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostRenamedSchemaRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostRenamedSchemaRequestWithBody generates requests for PostRenamedSchema with any type of body +func NewPostRenamedSchemaRequestWithBody(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("/renamed-schema") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewPatchResourceRequest calls the generic PatchResource builder with application/json body +func NewPatchResourceRequest(server string, id string, body PatchResourceJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPatchResourceRequestWithBody(server, id, "application/json", bodyReader) +} + +// NewPatchResourceRequestWithApplicationJSONPatchPlusJSONBody calls the generic PatchResource builder with application/json-patch+json body +func NewPatchResourceRequestWithApplicationJSONPatchPlusJSONBody(server string, id string, body PatchResourceApplicationJSONPatchPlusJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPatchResourceRequestWithBody(server, id, "application/json-patch+json", bodyReader) +} + +// NewPatchResourceRequestWithApplicationMergePatchPlusJSONBody calls the generic PatchResource builder with application/merge-patch+json body +func NewPatchResourceRequestWithApplicationMergePatchPlusJSONBody(server string, id string, body PatchResourceApplicationMergePatchPlusJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPatchResourceRequestWithBody(server, id, "application/merge-patch+json", bodyReader) +} + +// NewPatchResourceRequestWithBody generates requests for PatchResource with any type of body +func NewPatchResourceRequestWithBody(server string, id string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "id", id, 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("/resources/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PATCH", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetStatusRequest generates requests for GetStatus +func NewGetStatusRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/status") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetZapRequest generates requests for GetZap +func NewGetZapRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/zap") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostZapRequest calls the generic PostZap builder with application/json body +func NewPostZapRequest(server string, body PostZapJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostZapRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostZapRequestWithBody generates requests for PostZap with any type of body +func NewPostZapRequestWithBody(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("/zap") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +func (c *Client) 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 *Client) 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 { + // ListEntitiesWithResponse request + ListEntitiesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListEntitiesResponse, error) + + // PostFooWithBodyWithResponse request with any body + PostFooWithBodyWithResponse(ctx context.Context, params *PostFooParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFooResponse, error) + + PostFooWithResponse(ctx context.Context, params *PostFooParams, body PostFooJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFooResponse, error) + + // ListItemsWithResponse request + ListItemsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListItemsResponse2, error) + + // CreateItemWithBodyWithResponse request with any body + CreateItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateItemResponse2, error) + + CreateItemWithResponse(ctx context.Context, body CreateItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateItemResponse2, error) + + // CreateOrderWithBodyWithResponse request with any body + CreateOrderWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) + + CreateOrderWithResponse(ctx context.Context, body CreateOrderJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) + + CreateOrderWithApplicationJSONPatchPlusJSONBodyWithResponse(ctx context.Context, body CreateOrderApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) + + CreateOrderWithApplicationMergePatchPlusJSONBodyWithResponse(ctx context.Context, body CreateOrderApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) + + // GetOutcomeWithResponse request + GetOutcomeWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetOutcomeResponse, error) + + // PostOutcomeWithBodyWithResponse request with any body + PostOutcomeWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostOutcomeResponse, error) + + PostOutcomeWithResponse(ctx context.Context, body PostOutcomeJSONRequestBody, reqEditors ...RequestEditorFn) (*PostOutcomeResponse, error) + + // SendPayloadWithBodyWithResponse request with any body + SendPayloadWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SendPayloadResponse, error) + + SendPayloadWithResponse(ctx context.Context, body SendPayloadJSONRequestBody, reqEditors ...RequestEditorFn) (*SendPayloadResponse, error) + + // CreatePetWithBodyWithResponse request with any body + CreatePetWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreatePetResponse, error) + + CreatePetWithResponse(ctx context.Context, body CreatePetJSONRequestBody, reqEditors ...RequestEditorFn) (*CreatePetResponse, error) + + // QueryWithBodyWithResponse request with any body + QueryWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*QueryResponse2, error) + + QueryWithResponse(ctx context.Context, body QueryJSONRequestBody, reqEditors ...RequestEditorFn) (*QueryResponse2, error) + + // GetQuxWithResponse request + GetQuxWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetQuxResponse, error) + + // PostQuxWithBodyWithResponse request with any body + PostQuxWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostQuxResponse, error) + + PostQuxWithResponse(ctx context.Context, body PostQuxJSONRequestBody, reqEditors ...RequestEditorFn) (*PostQuxResponse, error) + + // GetRenamedSchemaWithResponse request + GetRenamedSchemaWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetRenamedSchemaResponse, error) + + // PostRenamedSchemaWithBodyWithResponse request with any body + PostRenamedSchemaWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostRenamedSchemaResponse, error) + + PostRenamedSchemaWithResponse(ctx context.Context, body PostRenamedSchemaJSONRequestBody, reqEditors ...RequestEditorFn) (*PostRenamedSchemaResponse, error) + + // PatchResourceWithBodyWithResponse request with any body + PatchResourceWithBodyWithResponse(ctx context.Context, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) + + PatchResourceWithResponse(ctx context.Context, id string, body PatchResourceJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) + + PatchResourceWithApplicationJSONPatchPlusJSONBodyWithResponse(ctx context.Context, id string, body PatchResourceApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) + + PatchResourceWithApplicationMergePatchPlusJSONBodyWithResponse(ctx context.Context, id string, body PatchResourceApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) + + // GetStatusWithResponse request + GetStatusWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetStatusResponse2, error) + + // GetZapWithResponse request + GetZapWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetZapResponse, error) + + // PostZapWithBodyWithResponse request with any body + PostZapWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostZapResponse, error) + + PostZapWithResponse(ctx context.Context, body PostZapJSONRequestBody, reqEditors ...RequestEditorFn) (*PostZapResponse, error) +} + +type ListEntitiesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Data *[]Widget `json:"data,omitempty"` + Metadata *Metadata `json:"metadata,omitempty"` + } +} + +// Status returns HTTPResponse.Status +func (r ListEntitiesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListEntitiesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostFooResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *BarResponse +} + +// Status returns HTTPResponse.Status +func (r PostFooResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostFooResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ListItemsResponse2 struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ListItemsResponse +} + +// Status returns HTTPResponse.Status +func (r ListItemsResponse2) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListItemsResponse2) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateItemResponse2 struct { + Body []byte + HTTPResponse *http.Response + JSON200 *CreateItemResponse +} + +// Status returns HTTPResponse.Status +func (r CreateItemResponse2) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateItemResponse2) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateOrderResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Order +} + +// Status returns HTTPResponse.Status +func (r CreateOrderResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateOrderResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetOutcomeResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *OutcomeResult +} + +// Status returns HTTPResponse.Status +func (r GetOutcomeResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetOutcomeResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostOutcomeResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostOutcomeResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostOutcomeResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type SendPayloadResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Payload +} + +// Status returns HTTPResponse.Status +func (r SendPayloadResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r SendPayloadResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreatePetResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Pet +} + +// Status returns HTTPResponse.Status +func (r CreatePetResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreatePetResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type QueryResponse2 struct { + Body []byte + HTTPResponse *http.Response + JSON200 *QueryResponse +} + +// Status returns HTTPResponse.Status +func (r QueryResponse2) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r QueryResponse2) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetQuxResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *QuxResponse +} + +// Status returns HTTPResponse.Status +func (r GetQuxResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetQuxResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostQuxResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostQuxResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostQuxResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetRenamedSchemaResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Renamer +} + +// Status returns HTTPResponse.Status +func (r GetRenamedSchemaResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetRenamedSchemaResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostRenamedSchemaResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostRenamedSchemaResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostRenamedSchemaResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PatchResourceResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *N200ResourcePatchResponseJSONApplicationJSON + ApplicationjsonPatchJSON200 *N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON + ApplicationjsonPatchQueryJSON200 *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON + ApplicationmergePatchJSON200 *N200ResourcePatchResponseJSON4ApplicationMergePatchPlusJSON +} +type PatchResource200ApplicationJSONPatchPlusJSON1 = []Resource +type PatchResource200ApplicationJSONPatchPlusJSON2 = string +type PatchResource200ApplicationJSONPatchQueryPlusJSON1 = []Resource +type PatchResource200ApplicationJSONPatchQueryPlusJSON2 = string + +// Status returns HTTPResponse.Status +func (r PatchResourceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PatchResourceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetStatusResponse2 struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetStatusResponse +} + +// Status returns HTTPResponse.Status +func (r GetStatusResponse2) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetStatusResponse2) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetZapResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ZapResponse +} + +// Status returns HTTPResponse.Status +func (r GetZapResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetZapResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostZapResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostZapResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostZapResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ListEntitiesWithResponse request returning *ListEntitiesResponse +func (c *ClientWithResponses) ListEntitiesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListEntitiesResponse, error) { + rsp, err := c.ListEntities(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseListEntitiesResponse(rsp) +} + +// PostFooWithBodyWithResponse request with arbitrary body returning *PostFooResponse +func (c *ClientWithResponses) PostFooWithBodyWithResponse(ctx context.Context, params *PostFooParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFooResponse, error) { + rsp, err := c.PostFooWithBody(ctx, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostFooResponse(rsp) +} + +func (c *ClientWithResponses) PostFooWithResponse(ctx context.Context, params *PostFooParams, body PostFooJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFooResponse, error) { + rsp, err := c.PostFoo(ctx, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostFooResponse(rsp) +} + +// ListItemsWithResponse request returning *ListItemsResponse2 +func (c *ClientWithResponses) ListItemsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListItemsResponse2, error) { + rsp, err := c.ListItems(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseListItemsResponse2(rsp) +} + +// CreateItemWithBodyWithResponse request with arbitrary body returning *CreateItemResponse2 +func (c *ClientWithResponses) CreateItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateItemResponse2, error) { + rsp, err := c.CreateItemWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateItemResponse2(rsp) +} + +func (c *ClientWithResponses) CreateItemWithResponse(ctx context.Context, body CreateItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateItemResponse2, error) { + rsp, err := c.CreateItem(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateItemResponse2(rsp) +} + +// CreateOrderWithBodyWithResponse request with arbitrary body returning *CreateOrderResponse +func (c *ClientWithResponses) CreateOrderWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) { + rsp, err := c.CreateOrderWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateOrderResponse(rsp) +} + +func (c *ClientWithResponses) CreateOrderWithResponse(ctx context.Context, body CreateOrderJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) { + rsp, err := c.CreateOrder(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateOrderResponse(rsp) +} + +func (c *ClientWithResponses) CreateOrderWithApplicationJSONPatchPlusJSONBodyWithResponse(ctx context.Context, body CreateOrderApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) { + rsp, err := c.CreateOrderWithApplicationJSONPatchPlusJSONBody(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateOrderResponse(rsp) +} + +func (c *ClientWithResponses) CreateOrderWithApplicationMergePatchPlusJSONBodyWithResponse(ctx context.Context, body CreateOrderApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateOrderResponse, error) { + rsp, err := c.CreateOrderWithApplicationMergePatchPlusJSONBody(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateOrderResponse(rsp) +} + +// GetOutcomeWithResponse request returning *GetOutcomeResponse +func (c *ClientWithResponses) GetOutcomeWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetOutcomeResponse, error) { + rsp, err := c.GetOutcome(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetOutcomeResponse(rsp) +} + +// PostOutcomeWithBodyWithResponse request with arbitrary body returning *PostOutcomeResponse +func (c *ClientWithResponses) PostOutcomeWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostOutcomeResponse, error) { + rsp, err := c.PostOutcomeWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostOutcomeResponse(rsp) +} + +func (c *ClientWithResponses) PostOutcomeWithResponse(ctx context.Context, body PostOutcomeJSONRequestBody, reqEditors ...RequestEditorFn) (*PostOutcomeResponse, error) { + rsp, err := c.PostOutcome(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostOutcomeResponse(rsp) +} + +// SendPayloadWithBodyWithResponse request with arbitrary body returning *SendPayloadResponse +func (c *ClientWithResponses) SendPayloadWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SendPayloadResponse, error) { + rsp, err := c.SendPayloadWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSendPayloadResponse(rsp) +} + +func (c *ClientWithResponses) SendPayloadWithResponse(ctx context.Context, body SendPayloadJSONRequestBody, reqEditors ...RequestEditorFn) (*SendPayloadResponse, error) { + rsp, err := c.SendPayload(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSendPayloadResponse(rsp) +} + +// CreatePetWithBodyWithResponse request with arbitrary body returning *CreatePetResponse +func (c *ClientWithResponses) CreatePetWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreatePetResponse, error) { + rsp, err := c.CreatePetWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreatePetResponse(rsp) +} + +func (c *ClientWithResponses) CreatePetWithResponse(ctx context.Context, body CreatePetJSONRequestBody, reqEditors ...RequestEditorFn) (*CreatePetResponse, error) { + rsp, err := c.CreatePet(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreatePetResponse(rsp) +} + +// QueryWithBodyWithResponse request with arbitrary body returning *QueryResponse2 +func (c *ClientWithResponses) QueryWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*QueryResponse2, error) { + rsp, err := c.QueryWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseQueryResponse2(rsp) +} + +func (c *ClientWithResponses) QueryWithResponse(ctx context.Context, body QueryJSONRequestBody, reqEditors ...RequestEditorFn) (*QueryResponse2, error) { + rsp, err := c.Query(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseQueryResponse2(rsp) +} + +// GetQuxWithResponse request returning *GetQuxResponse +func (c *ClientWithResponses) GetQuxWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetQuxResponse, error) { + rsp, err := c.GetQux(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetQuxResponse(rsp) +} + +// PostQuxWithBodyWithResponse request with arbitrary body returning *PostQuxResponse +func (c *ClientWithResponses) PostQuxWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostQuxResponse, error) { + rsp, err := c.PostQuxWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostQuxResponse(rsp) +} + +func (c *ClientWithResponses) PostQuxWithResponse(ctx context.Context, body PostQuxJSONRequestBody, reqEditors ...RequestEditorFn) (*PostQuxResponse, error) { + rsp, err := c.PostQux(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostQuxResponse(rsp) +} + +// GetRenamedSchemaWithResponse request returning *GetRenamedSchemaResponse +func (c *ClientWithResponses) GetRenamedSchemaWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetRenamedSchemaResponse, error) { + rsp, err := c.GetRenamedSchema(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetRenamedSchemaResponse(rsp) +} + +// PostRenamedSchemaWithBodyWithResponse request with arbitrary body returning *PostRenamedSchemaResponse +func (c *ClientWithResponses) PostRenamedSchemaWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostRenamedSchemaResponse, error) { + rsp, err := c.PostRenamedSchemaWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostRenamedSchemaResponse(rsp) +} + +func (c *ClientWithResponses) PostRenamedSchemaWithResponse(ctx context.Context, body PostRenamedSchemaJSONRequestBody, reqEditors ...RequestEditorFn) (*PostRenamedSchemaResponse, error) { + rsp, err := c.PostRenamedSchema(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostRenamedSchemaResponse(rsp) +} + +// PatchResourceWithBodyWithResponse request with arbitrary body returning *PatchResourceResponse +func (c *ClientWithResponses) PatchResourceWithBodyWithResponse(ctx context.Context, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) { + rsp, err := c.PatchResourceWithBody(ctx, id, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchResourceResponse(rsp) +} + +func (c *ClientWithResponses) PatchResourceWithResponse(ctx context.Context, id string, body PatchResourceJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) { + rsp, err := c.PatchResource(ctx, id, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchResourceResponse(rsp) +} + +func (c *ClientWithResponses) PatchResourceWithApplicationJSONPatchPlusJSONBodyWithResponse(ctx context.Context, id string, body PatchResourceApplicationJSONPatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) { + rsp, err := c.PatchResourceWithApplicationJSONPatchPlusJSONBody(ctx, id, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchResourceResponse(rsp) +} + +func (c *ClientWithResponses) PatchResourceWithApplicationMergePatchPlusJSONBodyWithResponse(ctx context.Context, id string, body PatchResourceApplicationMergePatchPlusJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchResourceResponse, error) { + rsp, err := c.PatchResourceWithApplicationMergePatchPlusJSONBody(ctx, id, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchResourceResponse(rsp) +} + +// GetStatusWithResponse request returning *GetStatusResponse2 +func (c *ClientWithResponses) GetStatusWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetStatusResponse2, error) { + rsp, err := c.GetStatus(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetStatusResponse2(rsp) +} + +// GetZapWithResponse request returning *GetZapResponse +func (c *ClientWithResponses) GetZapWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetZapResponse, error) { + rsp, err := c.GetZap(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetZapResponse(rsp) +} + +// PostZapWithBodyWithResponse request with arbitrary body returning *PostZapResponse +func (c *ClientWithResponses) PostZapWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostZapResponse, error) { + rsp, err := c.PostZapWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostZapResponse(rsp) +} + +func (c *ClientWithResponses) PostZapWithResponse(ctx context.Context, body PostZapJSONRequestBody, reqEditors ...RequestEditorFn) (*PostZapResponse, error) { + rsp, err := c.PostZap(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostZapResponse(rsp) +} + +// ParseListEntitiesResponse parses an HTTP response from a ListEntitiesWithResponse call +func ParseListEntitiesResponse(rsp *http.Response) (*ListEntitiesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListEntitiesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Data *[]Widget `json:"data,omitempty"` + Metadata *Metadata `json:"metadata,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostFooResponse parses an HTTP response from a PostFooWithResponse call +func ParsePostFooResponse(rsp *http.Response) (*PostFooResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostFooResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest BarResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseListItemsResponse2 parses an HTTP response from a ListItemsWithResponse call +func ParseListItemsResponse2(rsp *http.Response) (*ListItemsResponse2, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListItemsResponse2{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ListItemsResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateItemResponse2 parses an HTTP response from a CreateItemWithResponse call +func ParseCreateItemResponse2(rsp *http.Response) (*CreateItemResponse2, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateItemResponse2{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest CreateItemResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateOrderResponse parses an HTTP response from a CreateOrderWithResponse call +func ParseCreateOrderResponse(rsp *http.Response) (*CreateOrderResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateOrderResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Order + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetOutcomeResponse parses an HTTP response from a GetOutcomeWithResponse call +func ParseGetOutcomeResponse(rsp *http.Response) (*GetOutcomeResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetOutcomeResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest OutcomeResult + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostOutcomeResponse parses an HTTP response from a PostOutcomeWithResponse call +func ParsePostOutcomeResponse(rsp *http.Response) (*PostOutcomeResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostOutcomeResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseSendPayloadResponse parses an HTTP response from a SendPayloadWithResponse call +func ParseSendPayloadResponse(rsp *http.Response) (*SendPayloadResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &SendPayloadResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Payload + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreatePetResponse parses an HTTP response from a CreatePetWithResponse call +func ParseCreatePetResponse(rsp *http.Response) (*CreatePetResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreatePetResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Pet + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseQueryResponse2 parses an HTTP response from a QueryWithResponse call +func ParseQueryResponse2(rsp *http.Response) (*QueryResponse2, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &QueryResponse2{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest QueryResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetQuxResponse parses an HTTP response from a GetQuxWithResponse call +func ParseGetQuxResponse(rsp *http.Response) (*GetQuxResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetQuxResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest QuxResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostQuxResponse parses an HTTP response from a PostQuxWithResponse call +func ParsePostQuxResponse(rsp *http.Response) (*PostQuxResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostQuxResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetRenamedSchemaResponse parses an HTTP response from a GetRenamedSchemaWithResponse call +func ParseGetRenamedSchemaResponse(rsp *http.Response) (*GetRenamedSchemaResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetRenamedSchemaResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Renamer + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostRenamedSchemaResponse parses an HTTP response from a PostRenamedSchemaWithResponse call +func ParsePostRenamedSchemaResponse(rsp *http.Response) (*PostRenamedSchemaResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostRenamedSchemaResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParsePatchResourceResponse parses an HTTP response from a PatchResourceWithResponse call +func ParsePatchResourceResponse(rsp *http.Response) (*PatchResourceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PatchResourceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case rsp.Header.Get("Content-Type") == "application/json-patch+json" && rsp.StatusCode == 200: + var dest N200ResourcePatchResponseJSON2ApplicationJSONPatchPlusJSON + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.ApplicationjsonPatchJSON200 = &dest + + case rsp.Header.Get("Content-Type") == "application/json-patch-query+json" && rsp.StatusCode == 200: + var dest N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.ApplicationjsonPatchQueryJSON200 = &dest + + case rsp.Header.Get("Content-Type") == "application/json" && rsp.StatusCode == 200: + var dest N200ResourcePatchResponseJSONApplicationJSON + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case rsp.Header.Get("Content-Type") == "application/merge-patch+json" && rsp.StatusCode == 200: + var dest N200ResourcePatchResponseJSON4ApplicationMergePatchPlusJSON + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.ApplicationmergePatchJSON200 = &dest + + } + + return response, nil +} + +// ParseGetStatusResponse2 parses an HTTP response from a GetStatusWithResponse call +func ParseGetStatusResponse2(rsp *http.Response) (*GetStatusResponse2, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetStatusResponse2{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetStatusResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetZapResponse parses an HTTP response from a GetZapWithResponse call +func ParseGetZapResponse(rsp *http.Response) (*GetZapResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetZapResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ZapResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePostZapResponse parses an HTTP response from a PostZapWithResponse call +func ParsePostZapResponse(rsp *http.Response) (*PostZapResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostZapResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution_test.go b/internal/test/name_conflict_resolution/name_conflict_resolution_test.go new file mode 100644 index 0000000000..158f56f3f4 --- /dev/null +++ b/internal/test/name_conflict_resolution/name_conflict_resolution_test.go @@ -0,0 +1,460 @@ +package nameconflictresolution + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestCrossSectionCollisions verifies Pattern A: when the same name "Bar" +// appears in schemas, parameters, requestBodies, and responses, the resolver +// keeps the bare name for the component schema and suffixes the others. +// +// Covers issues: #200, #254, #407, #1881, PR #292 +func TestCrossSectionCollisions(t *testing.T) { + // Schema type keeps bare name "Bar" + bar := Bar{Value: ptr("hello")} + assert.Equal(t, "hello", *bar.Value) + + // No collision for Bar2 + bar2 := Bar2{Value: ptr(float32(1.5))} + assert.Equal(t, float32(1.5), *bar2.Value) + + // Parameter type gets "Parameter" suffix + param := BarParameter("query-value") + assert.Equal(t, "query-value", string(param)) + + // RequestBody type gets "RequestBody" suffix + reqBody := BarRequestBody{Value: ptr(42)} + assert.Equal(t, 42, *reqBody.Value) + + // Response type gets "Response" suffix + resp := BarResponse{ + Value1: &Bar{Value: ptr("v1")}, + Value2: &Bar2{Value: ptr(float32(2.0))}, + } + assert.Equal(t, "v1", *resp.Value1.Value) + assert.Equal(t, float32(2.0), *resp.Value2.Value) + + // PostFoo wrapper does not collide (unique name PostFooResponse) + var wrapper PostFooResponse + assert.Nil(t, wrapper.JSON200) + // JSON200 field points to the response type BarResponse (not schema type Bar) + wrapper.JSON200 = &resp + assert.Equal(t, "v1", *wrapper.JSON200.Value1.Value) +} + +// TestSchemaVsClientWrapper verifies Pattern B: schema "CreateItemResponse" +// collides with the client wrapper for operation "createItem". The schema +// keeps the bare name; the wrapper gets numeric fallback "CreateItemResponse2". +// +// Covers issues: #1474, #1713, #1450 +func TestSchemaVsClientWrapper(t *testing.T) { + // Schema type keeps bare name + schema := CreateItemResponse{ + Id: ptr("item-1"), + Name: ptr("Widget"), + } + assert.Equal(t, "item-1", *schema.Id) + assert.Equal(t, "Widget", *schema.Name) + + // Client wrapper gets numeric fallback + var wrapper CreateItemResponse2 + assert.Nil(t, wrapper.Body) + assert.Nil(t, wrapper.HTTPResponse) + assert.Nil(t, wrapper.JSON200) + + // JSON200 field references the schema type, not the wrapper itself + wrapper.JSON200 = &schema + assert.Equal(t, "item-1", *wrapper.JSON200.Id) +} + +// TestSchemaAliasVsClientWrapper verifies Pattern C: schema "ListItemsResponse" +// (a string alias) collides with the client wrapper for operation "listItems". +// The schema keeps the bare name; the wrapper gets "ListItemsResponse2". +// +// Covers issue: #1357 +func TestSchemaAliasVsClientWrapper(t *testing.T) { + // Schema type is a string alias + var schema ListItemsResponse = "item-list" + assert.Equal(t, "item-list", schema) + + // Client wrapper gets numeric fallback + var wrapper ListItemsResponse2 + assert.Nil(t, wrapper.Body) + assert.Nil(t, wrapper.HTTPResponse) + assert.Nil(t, wrapper.JSON200) + + // JSON200 field references the schema type (string alias) + wrapper.JSON200 = &schema + assert.Equal(t, "item-list", *wrapper.JSON200) +} + +// TestOperationNameMatchesSchema verifies Pattern D: schema "QueryResponse" +// collides with the client wrapper for operation "query" (which generates +// "QueryResponse"). The schema keeps the bare name; the wrapper gets +// "QueryResponse2". +// +// Covers issue: #255 +func TestOperationNameMatchesSchema(t *testing.T) { + // Schema type keeps bare name + schema := QueryResponse{ + Results: &[]string{"result1", "result2"}, + } + assert.Len(t, *schema.Results, 2) + + // Client wrapper gets numeric fallback + var wrapper QueryResponse2 + assert.Nil(t, wrapper.JSON200) + + // JSON200 field references the schema type + wrapper.JSON200 = &schema + assert.Len(t, *wrapper.JSON200.Results, 2) +} + +// TestSchemaMatchesOpResponse verifies Pattern E: schema "GetStatusResponse" +// collides with the client wrapper for operation "getStatus" (which generates +// "GetStatusResponse"). The schema keeps the bare name; the wrapper gets +// "GetStatusResponse2". +// +// Covers issues: #2097, #899 +func TestSchemaMatchesOpResponse(t *testing.T) { + // Schema type keeps bare name + schema := GetStatusResponse{ + Status: ptr("healthy"), + Timestamp: ptr("2025-01-01T00:00:00Z"), + } + assert.Equal(t, "healthy", *schema.Status) + assert.Equal(t, "2025-01-01T00:00:00Z", *schema.Timestamp) + + // Client wrapper gets numeric fallback + var wrapper GetStatusResponse2 + assert.Nil(t, wrapper.JSON200) + + // JSON200 field references the schema type + wrapper.JSON200 = &schema + assert.Equal(t, "healthy", *wrapper.JSON200.Status) +} + +// TestMultipleJsonContentTypes verifies Pattern H: schema "Order" collides with +// requestBody "Order" which has 3 content types that all contain "json": +// - application/json +// - application/merge-patch+json +// - application/json-patch+json +// +// All three map to the same "JSON" short name via contentTypeSuffix(), which +// would trigger an infinite oscillation between context suffix ("RequestBody") +// and content type suffix ("JSON") strategies if applied per-group. The global +// phase approach lets numeric fallback break the cycle. +// +// Expected types: +// - Order struct (schema keeps bare name) +// - OrderRequestBodyJSON struct (application/json requestBody) +// - OrderRequestBodyJSON2 []struct (application/json-patch+json, numeric fallback) +// - OrderRequestBodyJSON3 struct (application/merge-patch+json, numeric fallback) +// +// Covers: PR #2213 (multiple JSON content types in requestBody) +func TestMultipleJsonContentTypes(t *testing.T) { + // Schema type keeps bare name "Order" + order := Order{ + Id: ptr("order-1"), + Product: ptr("Widget"), + } + assert.Equal(t, "order-1", *order.Id) + assert.Equal(t, "Widget", *order.Product) + + // The 3 requestBody content types should each get a unique name. + // They all collide on "OrderRequestBodyJSON", so numeric fallback kicks in. + // The type names below are compile-time assertions that all 3 exist and are distinct. + + // application/json requestBody + jsonBody := OrderRequestBodyJSON{ + Id: ptr("order-2"), + Product: ptr("Gadget"), + } + assert.Equal(t, "order-2", *jsonBody.Id) + + // application/json-patch+json requestBody (numeric fallback, array type alias) + var jsonPatch OrderRequestBodyJSON2 + assert.Nil(t, jsonPatch) + + // application/merge-patch+json requestBody (numeric fallback) + mergePatch := OrderRequestBodyJSON3{ + Product: ptr("Gadget-patched"), + } + assert.Equal(t, "Gadget-patched", *mergePatch.Product) + + // CreateOrder wrapper should not collide + var wrapper CreateOrderResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &order + assert.Equal(t, "order-1", *wrapper.JSON200.Id) +} + +// TestRequestBodyVsSchema verifies that "Pet" in schemas and requestBodies +// resolves correctly: the schema keeps bare name "Pet", the requestBody +// gets "PetRequestBody". +// +// Covers issues: #254, #407 +func TestRequestBodyVsSchema(t *testing.T) { + // Schema type keeps bare name + pet := Pet{ + Id: ptr(1), + Name: ptr("Fluffy"), + } + assert.Equal(t, 1, *pet.Id) + assert.Equal(t, "Fluffy", *pet.Name) + + // RequestBody type gets "RequestBody" suffix + petReqBody := PetRequestBody{ + Name: ptr("Fluffy"), + Species: ptr("cat"), + } + assert.Equal(t, "Fluffy", *petReqBody.Name) + assert.Equal(t, "cat", *petReqBody.Species) + + // CreatePet wrapper doesn't collide (unique name CreatePetResponse) + var wrapper CreatePetResponse + assert.Nil(t, wrapper.JSON200) + + // JSON200 field references the schema type Pet + wrapper.JSON200 = &pet + assert.Equal(t, "Fluffy", *wrapper.JSON200.Name) +} + +// TestRefTargetPicksUpRename verifies that when an operation references a +// renamed component via $ref, the generated wrapper type uses the resolved +// (renamed) type, not the original spec name. +func TestRefTargetPicksUpRename(t *testing.T) { + // When postFoo references $ref: '#/components/responses/Bar', + // and response Bar is renamed to BarResponse, the wrapper's + // JSON200 field must use BarResponse (not Bar). + barResp := BarResponse{ + Value1: &Bar{Value: ptr("v1")}, + Value2: &Bar2{Value: ptr(float32(2.0))}, + } + var wrapper PostFooResponse + wrapper.JSON200 = &barResp // compile-time: JSON200 must be *BarResponse + assert.Equal(t, "v1", *wrapper.JSON200.Value1.Value) + assert.Equal(t, float32(2.0), *wrapper.JSON200.Value2.Value) +} + +// TestExtGoTypeNameWithCollisionResolver verifies that when a component schema +// has x-go-type-name: CustomQux and collides with a response "Qux", the +// collision resolver controls the top-level Go type names while x-go-type-name +// controls the underlying type definition. +// +// Expected types: +// - CustomQux struct (underlying type from x-go-type-name) +// - Qux = CustomQux (schema keeps bare name, aliased) +// - QuxResponse struct (response gets suffixed) +func TestExtGoTypeNameWithCollisionResolver(t *testing.T) { + // CustomQux is the underlying struct created by x-go-type-name + custom := CustomQux{Label: ptr("hello")} + assert.Equal(t, "hello", *custom.Label) + + // Qux is a type alias for CustomQux (schema keeps bare name) + var qux Qux = custom //nolint:staticcheck // explicit type needed to prove Qux aliases CustomQux + assert.Equal(t, "hello", *qux.Label) + + // QuxResponse is the response type (response gets suffixed) + quxResp := QuxResponse{Data: ptr("response-data")} + assert.Equal(t, "response-data", *quxResp.Data) + + // GetQuxResponse client wrapper's JSON200 field uses *QuxResponse + var wrapper GetQuxResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &quxResp + assert.Equal(t, "response-data", *wrapper.JSON200.Data) +} + +// TestExtGoTypeWithCollisionResolver verifies that when a component schema has +// x-go-type: string and collides with a response "Zap", the collision resolver +// controls the top-level Go type names while x-go-type controls the target type. +// +// Expected types: +// - Zap = string (schema keeps bare name, x-go-type controls target) +// - ZapResponse struct (response gets suffixed) +func TestExtGoTypeWithCollisionResolver(t *testing.T) { + // Zap is a string type alias (x-go-type controls the target) + var zap Zap = "test-value" + assert.Equal(t, "test-value", string(zap)) + + // ZapResponse is the response type (response gets suffixed) + zapResp := ZapResponse{Result: ptr("response-result")} + assert.Equal(t, "response-result", *zapResp.Result) + + // GetZapResponse client wrapper's JSON200 field uses *ZapResponse + var wrapper GetZapResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &zapResp + assert.Equal(t, "response-result", *wrapper.JSON200.Result) +} + +// TestInlineResponseWithRefProperties verifies Pattern I (oapi-codegen-exp#14): +// when a response has an inline object whose properties contain $refs to component +// schemas with x-go-type, the property-level refs must NOT produce duplicate type +// declarations. The component schemas keep their type aliases (Widget = string, +// Metadata = string), and the inline response object gets its own struct type. +// +// Covers: oapi-codegen-exp#14 +func TestInlineResponseWithRefProperties(t *testing.T) { + // Component schemas with x-go-type: string produce type aliases + var widget Widget = "widget-value" + assert.Equal(t, "widget-value", string(widget)) + + var metadata Metadata = "metadata-value" + assert.Equal(t, "metadata-value", string(metadata)) + + // The inline response object should have fields typed by the component aliases. + // The client wrapper for listEntities should exist and have a JSON200 field + // pointing to the inline response type. + var wrapper ListEntitiesResponse + assert.Nil(t, wrapper.JSON200) +} + +// TestDuplicateOneOfMembersAcrossContentTypes verifies Pattern J: +// when a response has multiple JSON content types (e.g., application/json-patch+json +// and application/json-patch-query+json) that share an identical oneOf schema with +// inline (non-$ref) members, the codegen must not emit duplicate type declarations +// for those inline members. +// +// Additionally, when a requestBody shares its name with a component schema and its +// content schemas $ref the component schema (plus one $refs a different schema), +// the collision resolver must assign unique names. +// +// Expected types: +// - ResourceMVO struct (schema keeps bare name) +// - Resource struct (no collision) +// - JsonPatch []struct (no collision) +// - ResourceMVORequestBodyJSON = ResourceMVO (requestBody application/json) +// - ResourceMVORequestBodyJSON2 = JsonPatch (requestBody application/json-patch+json) +// - ResourceMVORequestBodyJSON3 = ResourceMVO (requestBody application/merge-patch+json) +// - PatchResourceResponse struct (client response wrapper) +// - inline oneOf member types (must not be duplicated) +func TestDuplicateOneOfMembersAcrossContentTypes(t *testing.T) { + // Schema types keep bare names + resource := Resource{ + Id: ptr("res-1"), + Name: ptr("MyResource"), + Status: ptr("active"), + } + assert.Equal(t, "res-1", *resource.Id) + + resourceMVO := ResourceMVO{ + Name: ptr("MyResource"), + Status: ptr("active"), + } + assert.Equal(t, "MyResource", *resourceMVO.Name) + + // RequestBody collision resolution: schema "Resource_MVO" keeps bare name, + // requestBody content types get suffixed. + var reqBodyJSON ResourceMVORequestBodyJSON + reqBodyJSON.Name = ptr("test") + assert.Equal(t, "test", *reqBodyJSON.Name) + + var reqBodyPatch ResourceMVORequestBodyJSON2 + assert.Nil(t, reqBodyPatch) // JsonPatch alias (slice type) + + var reqBodyMerge ResourceMVORequestBodyJSON3 + reqBodyMerge.Name = ptr("merge") + assert.Equal(t, "merge", *reqBodyMerge.Name) + + // Client response wrapper should exist. The primary assertion here + // is that the package compiles — no duplicate oneOf member types and + // no undefined response type names. + var wrapper PatchResourceResponse + assert.Nil(t, wrapper.Body) + assert.Nil(t, wrapper.HTTPResponse) +} + +// TestXGoNameOnSchemaPreserved verifies Pattern K: when a component schema +// has x-go-name, the collision resolver must use the x-go-name value as the +// schema's type name (pinned), not the original spec name. +// +// Schema "Renamer" has x-go-name: "SpecialName" and shares a name with +// response "Renamer". With correct x-go-name handling the schema becomes +// "SpecialName", so no collision exists and the response keeps "Renamer". +// +// Expected types: +// - SpecialName struct (schema "Renamer" pinned by x-go-name) +// - Renamer struct (response "Renamer" — no collision) +// +// Covers: PR #2213 review finding (x-go-name not respected by resolver) +func TestXGoNameOnSchemaPreserved(t *testing.T) { + // Schema "Renamer" should use its x-go-name "SpecialName" + schema := SpecialName{Label: ptr("test-label")} + assert.Equal(t, "test-label", *schema.Label) + + // Response "Renamer" should keep its bare name (no collision with schema) + resp := Renamer{Data: ptr("response-data")} + assert.Equal(t, "response-data", *resp.Data) + + // Client wrapper for getRenamedSchema should reference the response type + var wrapper GetRenamedSchemaResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &resp + assert.Equal(t, "response-data", *wrapper.JSON200.Data) +} + +// TestXGoNameOnResponsePreserved verifies Pattern L: when a component response +// has x-go-name, the collision resolver must use the x-go-name value as the +// response's type name (pinned), not the original spec name. +// +// Response "Outcome" has x-go-name: "OutcomeResult" and shares a name with +// schema "Outcome". With correct x-go-name handling the response becomes +// "OutcomeResult", so no collision exists and the schema keeps "Outcome". +// +// Expected types: +// - Outcome struct (schema keeps bare name — no collision) +// - OutcomeResult struct (response "Outcome" pinned by x-go-name) +// +// Covers: PR #2213 review finding (x-go-name not respected by resolver) +func TestXGoNameOnResponsePreserved(t *testing.T) { + // Schema "Outcome" should keep its bare name + schema := Outcome{Value: ptr("some-value")} + assert.Equal(t, "some-value", *schema.Value) + + // Response "Outcome" should use its x-go-name "OutcomeResult" + resp := OutcomeResult{Result: ptr("outcome-data")} + assert.Equal(t, "outcome-data", *resp.Result) + + // Client wrapper for getOutcome should reference the response type + var wrapper GetOutcomeResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &resp + assert.Equal(t, "outcome-data", *wrapper.JSON200.Result) +} + +// TestXGoNameOnRequestBodyPreserved verifies Pattern M: when a component +// requestBody has x-go-name, the collision resolver must use the x-go-name +// value as the requestBody's type name (pinned), not the original spec name. +// +// RequestBody "Payload" has x-go-name: "PayloadBody" and shares a name with +// schema "Payload". With correct x-go-name handling the requestBody becomes +// "PayloadBody", so no collision exists and the schema keeps "Payload". +// +// Expected types: +// - Payload struct (schema keeps bare name — no collision) +// - PayloadBody struct (requestBody "Payload" pinned by x-go-name) +// +// Covers: PR #2213 review finding (x-go-name not respected by resolver) +func TestXGoNameOnRequestBodyPreserved(t *testing.T) { + // Schema "Payload" should keep its bare name + schema := Payload{Content: ptr("payload-content")} + assert.Equal(t, "payload-content", *schema.Content) + + // RequestBody "Payload" should use its x-go-name "PayloadBody" + reqBody := PayloadBody{Data: ptr("body-data")} + assert.Equal(t, "body-data", *reqBody.Data) + + // Client wrapper for sendPayload should reference the schema type + var wrapper SendPayloadResponse + assert.Nil(t, wrapper.JSON200) + wrapper.JSON200 = &schema + assert.Equal(t, "payload-content", *wrapper.JSON200.Content) +} + +func ptr[T any](v T) *T { + return &v +} diff --git a/internal/test/name_conflict_resolution/spec.yaml b/internal/test/name_conflict_resolution/spec.yaml new file mode 100644 index 0000000000..6cebbb9668 --- /dev/null +++ b/internal/test/name_conflict_resolution/spec.yaml @@ -0,0 +1,607 @@ +openapi: 3.0.1 + +info: + title: "Comprehensive name collision resolution test" + description: | + Exercises all documented name collision patterns across issues and PRs: + #200, #254, #255, #292, #407, #899, #1357, #1450, #1474, #1713, #1881, #2097, #2213 + Also covers oapi-codegen-exp#14 (inline response object with $ref properties). + Patterns K/L/M cover x-go-name preservation during collision resolution (PR #2213 review). + version: 0.0.0 + +paths: + # Pattern A: Cross-section collision (issues #200, #254, #407, #1881, PR #292) + # "Bar" appears in schemas, parameters, requestBodies, responses, and headers. + /foo: + post: + operationId: postFoo + parameters: + - $ref: '#/components/parameters/Bar' + requestBody: + $ref: '#/components/requestBodies/Bar' + responses: + 200: + $ref: '#/components/responses/Bar' + + # Pattern B: Schema vs client wrapper (issues #1474, #1713, #1450) + # Schema "CreateItemResponse" collides with createItem wrapper. + /items: + post: + operationId: createItem + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreateItemResponse' + + # Pattern C: Schema alias vs client wrapper (issue #1357) + # Schema "ListItemsResponse" (string alias) collides with listItems wrapper. + get: + operationId: listItems + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListItemsResponse' + + # Pattern D: Operation name = schema response name (issue #255) + # Schema "QueryResponse" collides with query wrapper. + /query: + post: + operationId: query + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + q: + type: string + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/QueryResponse' + + # Pattern E: Schema matches op+Response (issues #2097, #899) + # Schema "GetStatusResponse" collides with getStatus wrapper. + /status: + get: + operationId: getStatus + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetStatusResponse' + + # Pattern F: x-go-type-name extension + cross-section collision + # Schema "Qux" has x-go-type-name and collides with response "Qux". + /qux: + get: + operationId: getQux + responses: + '200': + $ref: '#/components/responses/Qux' + post: + operationId: postQux + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Qux' + responses: + '200': + description: OK + + # Pattern G: x-go-type extension + cross-section collision + # Schema "Zap" has x-go-type and collides with response "Zap". + /zap: + get: + operationId: getZap + responses: + '200': + $ref: '#/components/responses/Zap' + post: + operationId: postZap + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Zap' + responses: + '200': + description: OK + + # Pattern H: Multiple JSON content types in requestBody (PR #2213) + # "Order" appears in schemas and requestBodies. The requestBody has 3 content + # types that all contain "json" and collapse to the same "JSON" short name: + # application/json, application/merge-patch+json, application/json-patch+json + # This triggers an infinite oscillation between context suffix and content type + # suffix strategies unless the numeric fallback can break the cycle. + /orders: + post: + operationId: createOrder + requestBody: + $ref: '#/components/requestBodies/Order' + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + + # Pattern I: Inline response object with $ref properties to x-go-type schemas + # (oapi-codegen-exp#14). The response has an inline object with properties that + # $ref component schemas carrying x-go-type. Each property ref should use the + # component schema's type alias, not produce duplicate type declarations. + /entities: + get: + operationId: listEntities + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Widget' + metadata: + $ref: '#/components/schemas/Metadata' + + # Pattern J: Duplicate inline oneOf members across response content types + # A PATCH operation returns multiple JSON content types + # (application/json, application/json-patch+json, application/json-patch-query+json, + # application/merge-patch+json). The json-patch and json-patch-query variants + # share an identical oneOf schema with inline (non-$ref) members. The codegen + # must not emit duplicate type declarations for those inline members. + # + # Additionally, the requestBody shares the same name as a component schema + # ("Resource_MVO") where the requestBody content schemas $ref the component + # schema, and one content type $refs a different schema. + /resources/{id}: + patch: + operationId: patchResource + parameters: + - name: id + in: path + required: true + schema: + type: string + requestBody: + $ref: '#/components/requestBodies/Resource_MVO' + responses: + '200': + $ref: '#/components/responses/200Resource_Patch' + + # Pattern K: x-go-name on schema — resolver must preserve user-specified names + # Schema "Renamer" has x-go-name: "SpecialName". Response "Renamer" also exists. + # The resolver should use "SpecialName" for the schema (pinned by x-go-name) + # and "Renamer" for the response (no collision since the schema is "SpecialName"). + # Covers: PR #2213 review finding (x-go-name not respected by resolver) + /renamed-schema: + get: + operationId: getRenamedSchema + responses: + '200': + $ref: '#/components/responses/Renamer' + post: + operationId: postRenamedSchema + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Renamer' + responses: + '200': + description: OK + + # Pattern L: x-go-name on response — resolver must preserve user-specified names + # Response "Outcome" has x-go-name: "OutcomeResult". Schema "Outcome" also exists. + # The resolver should use "OutcomeResult" for the response (pinned by x-go-name) + # and "Outcome" for the schema (no collision since the response is "OutcomeResult"). + # Covers: PR #2213 review finding (x-go-name not respected by resolver) + /outcome: + get: + operationId: getOutcome + responses: + '200': + $ref: '#/components/responses/Outcome' + post: + operationId: postOutcome + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Outcome' + responses: + '200': + description: OK + + # Pattern M: x-go-name on requestBody — resolver must preserve user-specified names + # RequestBody "Payload" has x-go-name: "PayloadBody". Schema "Payload" also exists. + # The resolver should use "PayloadBody" for the requestBody (pinned by x-go-name) + # and "Payload" for the schema (no collision since the requestBody is "PayloadBody"). + # Covers: PR #2213 review finding (x-go-name not respected by resolver) + /payload: + post: + operationId: sendPayload + requestBody: + $ref: '#/components/requestBodies/Payload' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Payload' + + # Cross-section: requestBody vs schema (issues #254, #407) + # "Pet" appears in both schemas and requestBodies. + /pets: + post: + operationId: createPet + requestBody: + $ref: '#/components/requestBodies/Pet' + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + +components: + schemas: + Bar: + type: object + properties: + value: + type: string + + Bar2: + type: object + properties: + value: + type: number + + CreateItemResponse: + type: object + properties: + id: + type: string + name: + type: string + + ListItemsResponse: + type: string + + QueryResponse: + type: object + properties: + results: + type: array + items: + type: string + + GetStatusResponse: + type: object + properties: + status: + type: string + timestamp: + type: string + + # Pattern H: Schema "Order" collides with requestBody "Order" which has + # 3 content types that all map to the "JSON" short name. + Order: + type: object + properties: + id: + type: string + product: + type: string + + Pet: + type: object + properties: + id: + type: integer + name: + type: string + + # Pattern I: schemas with x-go-type used as $ref targets in inline response properties. + # (oapi-codegen-exp#14) + Widget: + type: object + x-go-type: string + properties: + id: + type: string + + Metadata: + type: object + x-go-type: string + properties: + total: + type: integer + + # Pattern J: schema "Resource_MVO" collides with requestBody "Resource_MVO". + # The requestBody's content schemas $ref the component schema, plus one + # content type $refs a different schema (JsonPatch). The response for the + # PATCH operation has multiple JSON content types, two of which share an + # identical oneOf schema with inline members. + Resource_MVO: + type: object + properties: + name: + type: string + status: + type: string + + Resource: + type: object + properties: + id: + type: string + name: + type: string + status: + type: string + + JsonPatch: + type: array + items: + type: object + properties: + op: + type: string + path: + type: string + + # Pattern K: x-go-name on schema — should be pinned as "SpecialName" + Renamer: + x-go-name: SpecialName + type: object + properties: + label: + type: string + + # Pattern L: schema "Outcome" (no x-go-name — keeps bare name) + Outcome: + type: object + properties: + value: + type: string + + # Pattern M: schema "Payload" (no x-go-name — keeps bare name) + Payload: + type: object + properties: + content: + type: string + + # Pattern F: x-go-type-name extension + cross-section collision + # Schema "Qux" has x-go-type-name: CustomQux and collides with response "Qux". + Qux: + type: object + x-go-type-name: CustomQux + properties: + label: + type: string + + # Pattern G: x-go-type extension + cross-section collision + # Schema "Zap" has x-go-type: string and collides with response "Zap". + Zap: + type: object + x-go-type: string + properties: + unused: + type: string + + parameters: + Bar: + name: bar + in: query + schema: + type: string + + requestBodies: + Bar: + content: + application/json: + schema: + type: object + properties: + value: + type: integer + + # Pattern H: requestBody "Order" with 3 content types that all contain "json" + # and collapse to the same "JSON" suffix via contentTypeSuffix(). + Order: + content: + application/json: + schema: + type: object + properties: + id: + type: string + product: + type: string + application/merge-patch+json: + schema: + type: object + properties: + product: + type: string + application/json-patch+json: + schema: + type: array + items: + type: object + properties: + op: + type: string + path: + type: string + value: + type: string + + Pet: + content: + application/json: + schema: + type: object + properties: + name: + type: string + species: + type: string + + # Pattern M: requestBody "Payload" has x-go-name — should be pinned as "PayloadBody" + Payload: + x-go-name: PayloadBody + content: + application/json: + schema: + type: object + properties: + data: + type: string + + # Pattern J: requestBody "Resource_MVO" shares name with schema "Resource_MVO". + # Content schemas $ref the component schema, except json-patch which $refs JsonPatch. + Resource_MVO: + content: + application/json: + schema: + $ref: '#/components/schemas/Resource_MVO' + application/merge-patch+json: + schema: + $ref: '#/components/schemas/Resource_MVO' + application/json-patch+json: + schema: + $ref: '#/components/schemas/JsonPatch' + + headers: + Bar: + schema: + type: boolean + + responses: + Bar: + description: Bar response + headers: + X-Bar: + $ref: '#/components/headers/Bar' + content: + application/json: + schema: + type: object + properties: + value1: + $ref: '#/components/schemas/Bar' + value2: + $ref: '#/components/schemas/Bar2' + + # Pattern K: response "Renamer" — no x-go-name, should keep bare name "Renamer" + # because the schema collision is avoided by the schema's x-go-name: SpecialName. + Renamer: + description: A Renamer response + content: + application/json: + schema: + type: object + properties: + data: + type: string + + # Pattern L: response "Outcome" has x-go-name — should be pinned as "OutcomeResult" + Outcome: + x-go-name: OutcomeResult + description: An Outcome response + content: + application/json: + schema: + type: object + properties: + result: + type: string + + Qux: + description: A Qux response + content: + application/json: + schema: + type: object + properties: + data: + type: string + + Zap: + description: A Zap response + content: + application/json: + schema: + type: object + properties: + result: + type: string + + # Pattern J: response with multiple JSON content types where json-patch + # and json-patch-query variants share an identical oneOf schema with + # inline (non-$ref) members. The codegen must not emit duplicate type + # declarations for those inline members. + 200Resource_Patch: + description: Patch success + content: + application/json: + schema: + $ref: '#/components/schemas/Resource' + application/merge-patch+json: + schema: + $ref: '#/components/schemas/Resource' + application/json-patch+json: + schema: + oneOf: + - $ref: '#/components/schemas/Resource' + - type: array + items: + $ref: '#/components/schemas/Resource' + - type: string + nullable: true + application/json-patch-query+json: + schema: + oneOf: + - $ref: '#/components/schemas/Resource' + - type: array + items: + $ref: '#/components/schemas/Resource' + - type: string + nullable: true diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 0f38b6ff7f..281574a68f 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -54,6 +54,12 @@ var globalState struct { initialismsMap map[string]string // typeMapping is the merged type mapping (defaults + user overrides). typeMapping TypeMapping + // resolvedNames maps schema path strings (e.g. "components/schemas/Pet") + // to their resolved Go type names, assigned by the multi-pass name resolver. + resolvedNames map[string]string + // resolvedClientWrapperNames maps operationID to the resolved Go type name + // for client response wrapper types (e.g., "createChatCompletion" -> "CreateChatCompletionResponseWrapper"). + resolvedClientWrapperNames map[string]string } // goImport represents a go package to be imported in the generated code @@ -176,6 +182,28 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { globalState.initialismsMap = makeInitialismsMap(opts.OutputOptions.AdditionalInitialisms) + // Multi-pass name resolution: gather all schemas, then resolve names globally. + // Only enabled when resolve-type-name-collisions is set. + if opts.OutputOptions.ResolveTypeNameCollisions { + gathered := GatherSchemas(spec, opts) + globalState.resolvedNames = ResolveNames(gathered) + // Build a separate operationID -> wrapper name lookup for genResponseTypeName. + // Keys must use the normalized operationID (via nameNormalizer) because + // OperationDefinition.OperationId is normalized before templates run. + globalState.resolvedClientWrapperNames = make(map[string]string) + for _, gs := range gathered { + if gs.Context == ContextClientResponseWrapper && gs.OperationID != "" { + if name, ok := globalState.resolvedNames[gs.Path.String()]; ok { + normalizedOpID := nameNormalizer(gs.OperationID) + globalState.resolvedClientWrapperNames[normalizedOpID] = name + } + } + } + } else { + globalState.resolvedNames = nil + globalState.resolvedClientWrapperNames = nil + } + // This creates the golang templates text package TemplateFunctions["opts"] = func() Configuration { return globalState.options } t := template.New("oapi-codegen").Funcs(TemplateFunctions) @@ -614,6 +642,10 @@ func GenerateTypesForSchemas(t *template.Template, schemas map[string]*openapi3. return nil, fmt.Errorf("error making name for components/schemas/%s: %w", schemaName, err) } + if resolved := resolvedNameForComponent("schemas", schemaName); resolved != "" { + goTypeName = resolved + } + types = append(types, TypeDefinition{ JsonName: schemaName, TypeName: goTypeName, @@ -642,6 +674,10 @@ func GenerateTypesForParameters(t *template.Template, params map[string]*openapi return nil, fmt.Errorf("error making name for components/parameters/%s: %w", paramName, err) } + if resolved := resolvedNameForComponent("parameters", paramName); resolved != "" { + goTypeName = resolved + } + typeDef := TypeDefinition{ JsonName: paramName, Schema: goType, @@ -689,7 +725,22 @@ func GenerateTypesForResponses(t *template.Template, responses openapi3.Response continue } - goType, err := GenerateGoSchema(response.Schema, []string{responseName}) + // When a response has multiple JSON content types, include the + // content type in the schema path so that inline types (e.g., + // oneOf union members) get unique names per content type. + // See the matching logic in GetResponseTypeDefinitions. + // + // We only add the content type segment when collision resolution + // is enabled (resolve-type-name-collisions) and jsonCount > 1, + // to avoid changing type names for existing users. Ideally the + // media type would always be part of the path for consistency. + // TODO: revisit this at the next major version change — + // always include the media type in the schema path. + schemaPath := []string{responseName} + if jsonCount > 1 && globalState.options.OutputOptions.ResolveTypeNameCollisions { + schemaPath = append(schemaPath, mediaTypeToCamelCase(mediaType)) + } + goType, err := GenerateGoSchema(response.Schema, schemaPath) if err != nil { return nil, fmt.Errorf("error generating Go type for schema in response %s: %w", responseName, err) } @@ -699,7 +750,9 @@ func GenerateTypesForResponses(t *template.Template, responses openapi3.Response return nil, fmt.Errorf("error making name for components/responses/%s: %w", responseName, err) } - goType.DefinedComp = ComponentTypeResponse + if resolved := resolvedNameForComponent("responses", responseName, mediaType); resolved != "" { + goTypeName = resolved + } typeDef := TypeDefinition{ JsonName: responseName, @@ -738,7 +791,8 @@ func GenerateTypesForRequestBodies(t *template.Template, bodies map[string]*open // As for responses, we will only generate Go code for JSON bodies, // the other body formats are up to the user. response := requestBodyRef.Value - for mediaType, body := range response.Content { + for _, mediaType := range SortedMapKeys(response.Content) { + body := response.Content[mediaType] if !util.IsMediaTypeJson(mediaType) { continue } @@ -753,7 +807,9 @@ func GenerateTypesForRequestBodies(t *template.Template, bodies map[string]*open return nil, fmt.Errorf("error making name for components/schemas/%s: %w", requestBodyName, err) } - goType.DefinedComp = ComponentTypeRequestBody + if resolved := resolvedNameForComponent("requestBodies", requestBodyName, mediaType); resolved != "" { + goTypeName = resolved + } typeDef := TypeDefinition{ JsonName: requestBodyName, @@ -782,15 +838,11 @@ func GenerateTypes(t *template.Template, types []TypeDefinition) (string, error) m := map[string]TypeDefinition{} var ts []TypeDefinition - if globalState.options.OutputOptions.ResolveTypeNameCollisions { - types = FixDuplicateTypeNames(types) - } - for _, typ := range types { if prevType, found := m[typ.TypeName]; found { - // If type names collide after auto-rename, we need to see if they - // refer to the same exact type definition, in which case, we can - // de-dupe. If they don't match, we error out. + // If type names collide, we need to see if they refer to the same + // exact type definition, in which case, we can de-dupe. If they + // don't match, we error out. if TypeDefinitionsEquivalent(prevType, typ) { continue } @@ -812,6 +864,63 @@ func GenerateTypes(t *template.Template, types []TypeDefinition) (string, error) return GenerateTemplates([]string{"typedef.tmpl"}, t, context) } +// resolvedNameForComponent looks up the resolved Go type name for a component +// identified by its section (e.g., "schemas", "parameters") and name. +// For content-bearing sections (responses, requestBodies), an optional +// contentType can be provided to match the exact media type entry. +// Returns empty string if no resolved name is available. +func resolvedNameForComponent(section, name string, contentType ...string) string { + if len(globalState.resolvedNames) == 0 { + return "" + } + + // Direct key match for schemas, parameters, headers + key := "components/" + section + "/" + name + if resolved, ok := globalState.resolvedNames[key]; ok { + return resolved + } + + // For responses and requestBodies, the path includes content type info. + // If a specific content type was provided, do an exact match. + if len(contentType) > 0 && contentType[0] != "" { + exactKey := key + "/content/" + contentType[0] + if resolved, ok := globalState.resolvedNames[exactKey]; ok { + return resolved + } + } + + // Fall back to prefix match for callers that don't specify content type. + // Sort matching keys so the result is deterministic across runs. + prefix := key + "/" + var matches []string + for k := range globalState.resolvedNames { + if strings.HasPrefix(k, prefix) { + matches = append(matches, k) + } + } + if len(matches) > 0 { + if len(matches) > 1 { + sort.Strings(matches) + } + return globalState.resolvedNames[matches[0]] + } + + return "" +} + +// resolvedNameForRefPath looks up the resolved Go type name for a $ref path +// like "#/components/responses/Foo", optionally scoped to a specific content type. +func resolvedNameForRefPath(refPath, contentType string) string { + if len(globalState.resolvedNames) == 0 || !strings.HasPrefix(refPath, "#/") { + return "" + } + parts := strings.Split(refPath, "/") + if len(parts) != 4 || parts[1] != "components" { + return "" + } + return resolvedNameForComponent(parts[2], parts[3], contentType) +} + func GenerateEnums(t *template.Template, types []TypeDefinition) (string, error) { enums := []EnumDefinition{} diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 4598bb04ad..6f4df06a0f 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -305,8 +305,10 @@ type OutputOptions struct { // types that collide across different OpenAPI component sections // (schemas, parameters, requestBodies, responses, headers) by appending // a suffix based on the component section (e.g., "Parameter", "Response", - // "RequestBody"). Without this, the codegen will error on duplicate type - // names, requiring manual resolution via x-go-name. + // "RequestBody"). It also detects collisions between component types and + // client response wrapper types (e.g., issue #1474). Without this, the + // codegen will error on duplicate type names, requiring manual resolution + // via x-go-name. ResolveTypeNameCollisions bool `yaml:"resolve-type-name-collisions,omitempty"` // TypeMapping allows customizing OpenAPI type/format to Go type mappings. diff --git a/pkg/codegen/extension.go b/pkg/codegen/extension.go index 6bc6bff144..dbf6611f4d 100644 --- a/pkg/codegen/extension.go +++ b/pkg/codegen/extension.go @@ -5,7 +5,10 @@ import ( ) const ( - // extPropGoType overrides the generated type definition. + // extPropGoType overrides the generated type definition. When + // resolve-type-name-collisions is enabled, the collision resolver + // controls the final Go type name; this extension controls what + // that name aliases or refers to. extPropGoType = "x-go-type" // extPropGoTypeSkipOptionalPointer specifies that optional fields should // be the type itself instead of a pointer to the type. @@ -14,7 +17,10 @@ const ( extPropGoImport = "x-go-type-import" // extGoName is used to override a field name extGoName = "x-go-name" - // extGoTypeName is used to override a generated typename for something. + // extGoTypeName overrides a generated typename. When + // resolve-type-name-collisions is enabled, the collision resolver + // controls the top-level Go type name; this extension controls + // the name of the underlying type definition that gets aliased. extGoTypeName = "x-go-type-name" extPropGoJsonIgnore = "x-go-json-ignore" extPropOmitEmpty = "x-omitempty" diff --git a/pkg/codegen/gather.go b/pkg/codegen/gather.go new file mode 100644 index 0000000000..84bd7e55df --- /dev/null +++ b/pkg/codegen/gather.go @@ -0,0 +1,331 @@ +package codegen + +import ( + "fmt" + "sort" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/oapi-codegen/oapi-codegen/v2/pkg/util" +) + +// SchemaPath represents the document location of a schema, e.g. +// ["components", "schemas", "Pet", "properties", "name"]. +type SchemaPath []string + +// String returns the path joined with "/". +func (sp SchemaPath) String() string { + return strings.Join(sp, "/") +} + +// SchemaContext identifies where in the OpenAPI document a schema was found. +type SchemaContext int + +const ( + ContextComponentSchema SchemaContext = iota + ContextComponentParameter + ContextComponentRequestBody + ContextComponentResponse + ContextComponentHeader + ContextOperationParameter + ContextOperationRequestBody + ContextOperationResponse + ContextClientResponseWrapper +) + +// String returns a human-readable name for the context. +func (sc SchemaContext) String() string { + switch sc { + case ContextComponentSchema: + return "Schema" + case ContextComponentParameter: + return "Parameter" + case ContextComponentRequestBody: + return "RequestBody" + case ContextComponentResponse: + return "Response" + case ContextComponentHeader: + return "Header" + case ContextOperationParameter: + return "OperationParameter" + case ContextOperationRequestBody: + return "OperationRequestBody" + case ContextOperationResponse: + return "OperationResponse" + case ContextClientResponseWrapper: + return "ClientResponseWrapper" + default: + return "Unknown" + } +} + +// Suffix returns the suffix to use for collision resolution. +func (sc SchemaContext) Suffix() string { + switch sc { + case ContextComponentSchema: + return "Schema" + case ContextComponentParameter, ContextOperationParameter: + return "Parameter" + case ContextComponentRequestBody, ContextOperationRequestBody: + return "RequestBody" + case ContextComponentResponse, ContextOperationResponse: + return "Response" + case ContextComponentHeader: + return "Header" + case ContextClientResponseWrapper: + return "Response" + default: + return "" + } +} + +// GatheredSchema represents a schema discovered during the gather pass, +// along with its document location and context metadata. +type GatheredSchema struct { + Path SchemaPath + Context SchemaContext + Ref string // $ref string if this is a reference + Schema *openapi3.Schema // The resolved schema value + OperationID string // Enclosing operation's ID, if any + ContentType string // Media type, if from request/response body + StatusCode string // HTTP status code, if from a response + ParamIndex int // Parameter index within an operation + ComponentName string // The component name (e.g., "Bar" for components/schemas/Bar) + GoNameOverride string // x-go-name override from the component or its parent container +} + +// IsComponentSchema returns true if this schema came from components/schemas. +func (gs *GatheredSchema) IsComponentSchema() bool { + return gs.Context == ContextComponentSchema +} + +// GatherSchemas walks the entire OpenAPI spec and collects all schemas that +// will need Go type names. This is the first pass of the multi-pass resolution. +func GatherSchemas(spec *openapi3.T, opts Configuration) []*GatheredSchema { + var schemas []*GatheredSchema + + if spec.Components != nil { + schemas = append(schemas, gatherComponentSchemas(spec.Components)...) + schemas = append(schemas, gatherComponentParameters(spec.Components)...) + schemas = append(schemas, gatherComponentResponses(spec.Components)...) + schemas = append(schemas, gatherComponentRequestBodies(spec.Components)...) + schemas = append(schemas, gatherComponentHeaders(spec.Components)...) + } + + // Gather client response wrapper types for operations that will generate + // client code. These synthetic entries exist so wrapper types like + // `CreateChatCompletionResponse` participate in collision detection. + if opts.Generate.Client { + schemas = append(schemas, gatherClientResponseWrappers(spec)...) + } + + return schemas +} + +func gatherComponentSchemas(components *openapi3.Components) []*GatheredSchema { + var result []*GatheredSchema + for _, name := range SortedSchemaKeys(components.Schemas) { + schemaRef := components.Schemas[name] + if schemaRef == nil || schemaRef.Value == nil { + continue + } + var goNameOverride string + if schemaRef.Ref == "" { + goNameOverride = extractGoNameOverride(schemaRef.Value.Extensions) + } + result = append(result, &GatheredSchema{ + Path: SchemaPath{"components", "schemas", name}, + Context: ContextComponentSchema, + Ref: schemaRef.Ref, + Schema: schemaRef.Value, + ComponentName: name, + GoNameOverride: goNameOverride, + }) + } + return result +} + +func gatherComponentParameters(components *openapi3.Components) []*GatheredSchema { + var result []*GatheredSchema + for _, name := range SortedMapKeys(components.Parameters) { + paramRef := components.Parameters[name] + if paramRef == nil || paramRef.Value == nil { + continue + } + param := paramRef.Value + if param.Schema != nil && param.Schema.Value != nil { + var goNameOverride string + if paramRef.Ref == "" { + goNameOverride = extractGoNameOverride(param.Extensions) + } + result = append(result, &GatheredSchema{ + Path: SchemaPath{"components", "parameters", name}, + Context: ContextComponentParameter, + Ref: paramRef.Ref, + Schema: param.Schema.Value, + ComponentName: name, + GoNameOverride: goNameOverride, + }) + } + } + return result +} + +func gatherComponentResponses(components *openapi3.Components) []*GatheredSchema { + var result []*GatheredSchema + for _, name := range SortedMapKeys(components.Responses) { + responseRef := components.Responses[name] + if responseRef == nil || responseRef.Value == nil { + continue + } + response := responseRef.Value + var goNameOverride string + if responseRef.Ref == "" { + goNameOverride = extractGoNameOverride(response.Extensions) + } + for _, mediaType := range SortedMapKeys(response.Content) { + if !util.IsMediaTypeJson(mediaType) { + continue + } + mt := response.Content[mediaType] + if mt.Schema != nil && mt.Schema.Value != nil { + result = append(result, &GatheredSchema{ + Path: SchemaPath{"components", "responses", name, "content", mediaType}, + Context: ContextComponentResponse, + Ref: responseRef.Ref, + Schema: mt.Schema.Value, + ContentType: mediaType, + ComponentName: name, + GoNameOverride: goNameOverride, + }) + } + } + } + return result +} + +func gatherComponentRequestBodies(components *openapi3.Components) []*GatheredSchema { + var result []*GatheredSchema + for _, name := range SortedMapKeys(components.RequestBodies) { + bodyRef := components.RequestBodies[name] + if bodyRef == nil || bodyRef.Value == nil { + continue + } + body := bodyRef.Value + var goNameOverride string + if bodyRef.Ref == "" { + goNameOverride = extractGoNameOverride(body.Extensions) + } + for _, mediaType := range SortedMapKeys(body.Content) { + if !util.IsMediaTypeJson(mediaType) { + continue + } + mt := body.Content[mediaType] + if mt.Schema != nil && mt.Schema.Value != nil { + result = append(result, &GatheredSchema{ + Path: SchemaPath{"components", "requestBodies", name, "content", mediaType}, + Context: ContextComponentRequestBody, + Ref: bodyRef.Ref, + Schema: mt.Schema.Value, + ContentType: mediaType, + ComponentName: name, + GoNameOverride: goNameOverride, + }) + } + } + } + return result +} + +func gatherComponentHeaders(components *openapi3.Components) []*GatheredSchema { + var result []*GatheredSchema + for _, name := range SortedMapKeys(components.Headers) { + headerRef := components.Headers[name] + if headerRef == nil || headerRef.Value == nil { + continue + } + header := headerRef.Value + if header.Schema != nil && header.Schema.Value != nil { + var goNameOverride string + if headerRef.Ref == "" { + goNameOverride = extractGoNameOverride(header.Extensions) + } + result = append(result, &GatheredSchema{ + Path: SchemaPath{"components", "headers", name}, + Context: ContextComponentHeader, + Ref: headerRef.Ref, + Schema: header.Schema.Value, + ComponentName: name, + GoNameOverride: goNameOverride, + }) + } + } + return result +} + +// gatherClientResponseWrappers creates synthetic schema entries for each +// operation that would generate a client response wrapper type like +// `Response`. These don't correspond to a real schema in the +// spec but they need names that don't collide with real types. +func gatherClientResponseWrappers(spec *openapi3.T) []*GatheredSchema { + var result []*GatheredSchema + + if spec.Paths == nil { + return result + } + + // Collect all operations sorted for determinism + type opEntry struct { + path string + method string + op *openapi3.Operation + } + var ops []opEntry + + pathKeys := SortedMapKeys(spec.Paths.Map()) + for _, path := range pathKeys { + pathItem := spec.Paths.Find(path) + if pathItem == nil { + continue + } + for method, op := range pathItem.Operations() { + if op != nil && op.OperationID != "" { + ops = append(ops, opEntry{path: path, method: method, op: op}) + } + } + } + + // Sort by operationID for determinism + sort.Slice(ops, func(i, j int) bool { + return ops[i].op.OperationID < ops[j].op.OperationID + }) + + for _, entry := range ops { + result = append(result, &GatheredSchema{ + Path: SchemaPath{"paths", entry.path, entry.method, "x-client-response-wrapper"}, + Context: ContextClientResponseWrapper, + OperationID: entry.op.OperationID, + }) + } + + return result +} + +// FormatPath returns a human-readable representation of the path for debugging. +func (gs *GatheredSchema) FormatPath() string { + return fmt.Sprintf("#/%s", strings.Join(gs.Path, "/")) +} + +// extractGoNameOverride reads the x-go-name extension from extensions and +// returns its value, or "" if not present or invalid. +func extractGoNameOverride(extensions map[string]any) string { + ext, ok := extensions[extGoName] + if !ok { + return "" + } + name, err := extTypeName(ext) + if err != nil { + return "" + } + return name +} diff --git a/pkg/codegen/gather_test.go b/pkg/codegen/gather_test.go new file mode 100644 index 0000000000..24e63b000b --- /dev/null +++ b/pkg/codegen/gather_test.go @@ -0,0 +1,356 @@ +package codegen + +import ( + "testing" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGatherSchemas_ComponentSchemas(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Schemas: openapi3.Schemas{ + "Pet": &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + "Owner": &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 2) + + // Sorted order: Owner, Pet + assert.Equal(t, SchemaPath{"components", "schemas", "Owner"}, schemas[0].Path) + assert.Equal(t, ContextComponentSchema, schemas[0].Context) + assert.Equal(t, "Owner", schemas[0].ComponentName) + + assert.Equal(t, SchemaPath{"components", "schemas", "Pet"}, schemas[1].Path) + assert.Equal(t, ContextComponentSchema, schemas[1].Context) + assert.Equal(t, "Pet", schemas[1].ComponentName) +} + +func TestGatherSchemas_ComponentParameters(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Parameters: openapi3.ParametersMap{ + "Limit": &openapi3.ParameterRef{ + Value: &openapi3.Parameter{ + Name: "limit", + In: "query", + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"integer"}}, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, SchemaPath{"components", "parameters", "Limit"}, schemas[0].Path) + assert.Equal(t, ContextComponentParameter, schemas[0].Context) + assert.Equal(t, "Limit", schemas[0].ComponentName) +} + +func TestGatherSchemas_ComponentResponses(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Responses: openapi3.ResponseBodies{ + "Error": &openapi3.ResponseRef{ + Value: &openapi3.Response{ + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, SchemaPath{"components", "responses", "Error", "content", "application/json"}, schemas[0].Path) + assert.Equal(t, ContextComponentResponse, schemas[0].Context) + assert.Equal(t, "Error", schemas[0].ComponentName) + assert.Equal(t, "application/json", schemas[0].ContentType) +} + +func TestGatherSchemas_ComponentRequestBodies(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + RequestBodies: openapi3.RequestBodies{ + "CreatePet": &openapi3.RequestBodyRef{ + Value: &openapi3.RequestBody{ + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, SchemaPath{"components", "requestBodies", "CreatePet", "content", "application/json"}, schemas[0].Path) + assert.Equal(t, ContextComponentRequestBody, schemas[0].Context) + assert.Equal(t, "CreatePet", schemas[0].ComponentName) +} + +func TestGatherSchemas_ComponentHeaders(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Headers: openapi3.Headers{ + "X-Rate-Limit": &openapi3.HeaderRef{ + Value: &openapi3.Header{ + Parameter: openapi3.Parameter{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"integer"}}, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, SchemaPath{"components", "headers", "X-Rate-Limit"}, schemas[0].Path) + assert.Equal(t, ContextComponentHeader, schemas[0].Context) +} + +func TestGatherSchemas_ClientResponseWrappers(t *testing.T) { + paths := openapi3.NewPaths() + paths.Set("/pets", &openapi3.PathItem{ + Get: &openapi3.Operation{ + OperationID: "listPets", + }, + Post: &openapi3.Operation{ + OperationID: "createPet", + }, + }) + + spec := &openapi3.T{ + Paths: paths, + } + + // Without client generation, no wrappers + opts := Configuration{Generate: GenerateOptions{Client: false}} + schemas := GatherSchemas(spec, opts) + assert.Len(t, schemas, 0) + + // With client generation, wrappers are gathered + opts = Configuration{Generate: GenerateOptions{Client: true}} + schemas = GatherSchemas(spec, opts) + assert.Len(t, schemas, 2) + + // Check they're sorted by operationID + assert.Equal(t, ContextClientResponseWrapper, schemas[0].Context) + assert.Equal(t, "createPet", schemas[0].OperationID) + assert.Equal(t, ContextClientResponseWrapper, schemas[1].Context) + assert.Equal(t, "listPets", schemas[1].OperationID) +} + +func TestGatherSchemas_GoNameOverride_Schema(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Schemas: openapi3.Schemas{ + "Renamer": &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Type: &openapi3.Types{"object"}, + Extensions: map[string]any{"x-go-name": "SpecialName"}, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, "SpecialName", schemas[0].GoNameOverride) +} + +func TestGatherSchemas_GoNameOverride_Response(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Responses: openapi3.ResponseBodies{ + "Outcome": &openapi3.ResponseRef{ + Value: &openapi3.Response{ + Extensions: map[string]any{"x-go-name": "OutcomeResult"}, + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, "OutcomeResult", schemas[0].GoNameOverride) +} + +func TestGatherSchemas_GoNameOverride_RequestBody(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + RequestBodies: openapi3.RequestBodies{ + "Payload": &openapi3.RequestBodyRef{ + Value: &openapi3.RequestBody{ + Extensions: map[string]any{"x-go-name": "PayloadBody"}, + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, "PayloadBody", schemas[0].GoNameOverride) +} + +func TestGatherSchemas_GoNameOverride_SkippedForRef(t *testing.T) { + spec := &openapi3.T{ + Components: &openapi3.Components{ + Schemas: openapi3.Schemas{ + "AliasedPet": &openapi3.SchemaRef{ + Ref: "#/components/schemas/Pet", + Value: &openapi3.Schema{ + Type: &openapi3.Types{"object"}, + Extensions: map[string]any{"x-go-name": "ShouldBeIgnored"}, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + require.Len(t, schemas, 1) + assert.Equal(t, "", schemas[0].GoNameOverride) +} + +func TestGatherSchemas_AllSections(t *testing.T) { + // Spec with "Bar" in schemas, parameters, responses, requestBodies, headers + // This is the issue #200 scenario (cross-section collision) + paths := openapi3.NewPaths() + spec := &openapi3.T{ + Paths: paths, + Components: &openapi3.Components{ + Schemas: openapi3.Schemas{ + "Bar": &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + Parameters: openapi3.ParametersMap{ + "Bar": &openapi3.ParameterRef{ + Value: &openapi3.Parameter{ + Name: "Bar", + In: "query", + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"string"}}, + }, + }, + }, + }, + Responses: openapi3.ResponseBodies{ + "Bar": &openapi3.ResponseRef{ + Value: &openapi3.Response{ + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + RequestBodies: openapi3.RequestBodies{ + "Bar": &openapi3.RequestBodyRef{ + Value: &openapi3.RequestBody{ + Content: openapi3.Content{ + "application/json": &openapi3.MediaType{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"object"}}, + }, + }, + }, + }, + }, + }, + Headers: openapi3.Headers{ + "Bar": &openapi3.HeaderRef{ + Value: &openapi3.Header{ + Parameter: openapi3.Parameter{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{Type: &openapi3.Types{"boolean"}}, + }, + }, + }, + }, + }, + }, + } + + opts := Configuration{} + schemas := GatherSchemas(spec, opts) + + // Should have 5 entries: schema, parameter, response, requestBody, header + assert.Len(t, schemas, 5) + + // Verify contexts are all different + contexts := make(map[SchemaContext]bool) + for _, s := range schemas { + contexts[s.Context] = true + } + assert.True(t, contexts[ContextComponentSchema]) + assert.True(t, contexts[ContextComponentParameter]) + assert.True(t, contexts[ContextComponentResponse]) + assert.True(t, contexts[ContextComponentRequestBody]) + assert.True(t, contexts[ContextComponentHeader]) +} diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index eb6e3e1fd3..3c639d22dc 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -342,7 +342,29 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini contentType := responseRef.Value.Content[contentTypeName] // We can only generate a type if we have a schema: if contentType.Schema != nil { - responseSchema, err := GenerateGoSchema(contentType.Schema, []string{o.OperationId, responseName}) + // When a response has multiple JSON content types (e.g., + // application/json, application/json-patch+json, and + // application/merge-patch+json), we include a content-type-derived + // segment in the schema path. This is necessary because + // GenerateGoSchema uses the path to name any inline types it + // creates (e.g., oneOf union members). Without the content type + // in the path, all content types for the same response produce + // identically-named inline types. If those content types have + // different schemas, the result is conflicting type declarations; + // if they have the same schema, the result is duplicate + // declarations. Both cases produce code that won't compile. + // + // We only add the content type segment when collision resolution + // is enabled (resolve-type-name-collisions) and jsonCount > 1, + // to avoid changing type names for existing users. Ideally the + // media type would always be part of the path for consistency. + // TODO: revisit this at the next major version change — + // always include the media type in the schema path. + schemaPath := []string{o.OperationId, responseName} + if jsonCount > 1 && util.IsMediaTypeJson(contentTypeName) && globalState.options.OutputOptions.ResolveTypeNameCollisions { + schemaPath = append(schemaPath, mediaTypeToCamelCase(contentTypeName)) + } + responseSchema, err := GenerateGoSchema(contentType.Schema, schemaPath) if err != nil { return nil, fmt.Errorf("unable to determine Go type for %s.%s: %w", o.OperationId, contentTypeName, err) } @@ -386,7 +408,11 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini return nil, fmt.Errorf("error dereferencing response Ref: %w", err) } if jsonCount > 1 && util.IsMediaTypeJson(contentTypeName) { - refType += mediaTypeToCamelCase(contentTypeName) + if resolved := resolvedNameForRefPath(responseRef.Ref, contentTypeName); resolved != "" { + refType = resolved + mediaTypeToCamelCase(contentTypeName) + } else { + refType += mediaTypeToCamelCase(contentTypeName) + } } td.Schema.RefType = refType } diff --git a/pkg/codegen/resolve_names.go b/pkg/codegen/resolve_names.go new file mode 100644 index 0000000000..f6d65f5b92 --- /dev/null +++ b/pkg/codegen/resolve_names.go @@ -0,0 +1,339 @@ +package codegen + +import ( + "fmt" + "sort" + "strconv" + "strings" +) + +// ResolvedName holds the final Go type name assigned to a gathered schema. +type ResolvedName struct { + Schema *GatheredSchema + GoName string // The resolved Go type name + Candidate string // The initial candidate name before collision resolution + Pinned bool // True if name came from x-go-name; must not be renamed +} + +// ResolveNames takes the gathered schemas and assigns unique Go type names to each. +// It returns a map from the schema's path string to the resolved Go type name. +func ResolveNames(schemas []*GatheredSchema) map[string]string { + // Step 1: Generate candidate names for all schemas + candidates := make([]*ResolvedName, len(schemas)) + for i, s := range schemas { + candidate := generateCandidateName(s) + candidates[i] = &ResolvedName{ + Schema: s, + GoName: candidate, + Candidate: candidate, + Pinned: s.GoNameOverride != "", + } + } + + // Step 2: Resolve collisions iteratively + resolveCollisions(candidates) + + // Step 3: Build the result map + result := make(map[string]string, len(candidates)) + for _, c := range candidates { + result[c.Schema.Path.String()] = c.GoName + } + return result +} + +// generateCandidateName produces an initial Go type name candidate based on +// the schema's location and context in the OpenAPI document. +func generateCandidateName(s *GatheredSchema) string { + if s.GoNameOverride != "" { + return s.GoNameOverride + } + + switch s.Context { + case ContextComponentSchema: + return SchemaNameToTypeName(s.ComponentName) + + case ContextComponentParameter: + return SchemaNameToTypeName(s.ComponentName) + + case ContextComponentResponse: + return SchemaNameToTypeName(s.ComponentName) + + case ContextComponentRequestBody: + return SchemaNameToTypeName(s.ComponentName) + + case ContextComponentHeader: + return SchemaNameToTypeName(s.ComponentName) + + case ContextClientResponseWrapper: + // Client response wrappers use: OperationId + responseTypeSuffix + return fmt.Sprintf("%s%s", SchemaNameToTypeName(s.OperationID), responseTypeSuffix) + + case ContextOperationParameter: + if s.OperationID != "" { + return SchemaNameToTypeName(s.OperationID) + "Parameter" + } + return SchemaNameToTypeName(s.ComponentName) + "Parameter" + + case ContextOperationRequestBody: + if s.OperationID != "" { + ct := contentTypeSuffix(s.ContentType) + return SchemaNameToTypeName(s.OperationID) + ct + "Request" + } + return SchemaNameToTypeName(s.ComponentName) + "Request" + + case ContextOperationResponse: + if s.OperationID != "" { + ct := contentTypeSuffix(s.ContentType) + return SchemaNameToTypeName(s.OperationID) + s.StatusCode + ct + "Response" + } + return SchemaNameToTypeName(s.ComponentName) + "Response" + + default: + return SchemaNameToTypeName(s.ComponentName) + } +} + +// resolveCollisions detects and resolves naming collisions among the resolved names. +// It applies strategies in global phases of increasing aggressiveness: +// 1. Context suffix (Schema, Parameter, Response, etc.) +// 2. Per-schema disambiguation (content type, status code, etc.) +// 3. Numeric fallback +// +// Each strategy is applied to ALL colliding groups, then collisions are +// re-checked globally before moving to the next strategy. This prevents +// oscillation between strategies (e.g., context suffix and content type +// suffix repeatedly appending to the same names without resolution). +func resolveCollisions(names []*ResolvedName) { + strategies := []func([]*ResolvedName) bool{ + strategyContextSuffix, + strategyPerSchemaDisambiguate, + strategyNumericFallback, + } + + const maxIterations = 20 + + for _, strategy := range strategies { + for iter := 0; iter < maxIterations; iter++ { + groups := groupByName(names) + anyCollision := false + anyProgress := false + for _, group := range groups { + if len(group) <= 1 { + continue + } + anyCollision = true + if strategy(group) { + anyProgress = true + } + } + if !anyCollision { + return + } + if !anyProgress { + break // This strategy can't help; try the next one + } + } + } +} + +// groupByName groups ResolvedNames by their current GoName. +func groupByName(names []*ResolvedName) map[string][]*ResolvedName { + groups := make(map[string][]*ResolvedName) + for _, n := range names { + groups[n.GoName] = append(groups[n.GoName], n) + } + return groups +} + +// strategyContextSuffix attempts to resolve collisions by appending a suffix +// derived from the schema's context (Schema, Parameter, Response, etc.). +// Component schemas are "privileged" — if exactly one member is a component +// schema, it keeps the bare name and only the others get suffixed. +// Returns true if any name was modified, false if no progress was made. +func strategyContextSuffix(group []*ResolvedName) bool { + // Count how many are component schemas (privileged) + var componentSchemaCount int + for _, n := range group { + if n.Schema.IsComponentSchema() { + componentSchemaCount++ + } + } + + progress := false + for _, n := range group { + if n.Pinned { + continue + } + + suffix := n.Schema.Context.Suffix() + if suffix == "" { + continue + } + + // If exactly one is a component schema, it keeps the bare name + if componentSchemaCount == 1 && n.Schema.IsComponentSchema() { + continue + } + + // Don't add suffix if name already ends with it + if strings.HasSuffix(n.GoName, suffix) { + continue + } + + n.GoName = n.GoName + suffix + progress = true + } + return progress +} + +// strategyPerSchemaDisambiguate tries several per-schema disambiguation strategies. +// Returns true if any name was modified, false if no progress was made. +func strategyPerSchemaDisambiguate(group []*ResolvedName) bool { + progress := tryContentTypeSuffix(group) + if !progress && tryStatusCodeSuffix(group) { + progress = true + } + if !progress && tryParamIndexSuffix(group) { + progress = true + } + return progress +} + +// tryContentTypeSuffix appends a content type discriminator when schemas +// differ by media type (e.g., JSON vs XML). +// Returns true if any name was modified, false if no progress was made. +func tryContentTypeSuffix(group []*ResolvedName) bool { + // Check if any members have different content types + contentTypes := make(map[string]bool) + for _, n := range group { + if n.Schema.ContentType != "" { + contentTypes[n.Schema.ContentType] = true + } + } + if len(contentTypes) <= 1 { + return false + } + + progress := false + for _, n := range group { + if n.Pinned { + continue + } + if n.Schema.ContentType == "" { + continue + } + suffix := contentTypeSuffix(n.Schema.ContentType) + if suffix != "" && !strings.HasSuffix(n.GoName, suffix) { + n.GoName = n.GoName + suffix + progress = true + } + } + return progress +} + +// tryStatusCodeSuffix appends the HTTP status code when schemas differ by status. +// Returns true if any name was modified, false if no progress was made. +func tryStatusCodeSuffix(group []*ResolvedName) bool { + statusCodes := make(map[string]bool) + for _, n := range group { + if n.Schema.StatusCode != "" { + statusCodes[n.Schema.StatusCode] = true + } + } + if len(statusCodes) <= 1 { + return false + } + + progress := false + for _, n := range group { + if n.Pinned { + continue + } + if n.Schema.StatusCode != "" && !strings.HasSuffix(n.GoName, n.Schema.StatusCode) { + n.GoName = n.GoName + n.Schema.StatusCode + progress = true + } + } + return progress +} + +// tryParamIndexSuffix appends a parameter index when schemas differ by position. +// Returns true if any name was modified, false if no progress was made. +func tryParamIndexSuffix(group []*ResolvedName) bool { + hasMultipleParams := false + for i := 0; i < len(group); i++ { + for j := i + 1; j < len(group); j++ { + if group[i].Schema.ParamIndex != group[j].Schema.ParamIndex { + hasMultipleParams = true + break + } + } + if hasMultipleParams { + break + } + } + if !hasMultipleParams { + return false + } + + progress := false + for _, n := range group { + if n.Pinned { + continue + } + suffix := strconv.Itoa(n.Schema.ParamIndex) + if !strings.HasSuffix(n.GoName, suffix) { + n.GoName = n.GoName + suffix + progress = true + } + } + return progress +} + +// strategyNumericFallback is the last resort: append increasing numbers. +// Returns true if any name was modified (always true when group has 2+ members). +func strategyNumericFallback(group []*ResolvedName) bool { + // Sort for determinism: pinned first, then component schemas, then by path + sort.Slice(group, func(i, j int) bool { + if group[i].Pinned != group[j].Pinned { + return group[i].Pinned + } + if group[i].Schema.IsComponentSchema() != group[j].Schema.IsComponentSchema() { + return group[i].Schema.IsComponentSchema() + } + return group[i].Schema.Path.String() < group[j].Schema.Path.String() + }) + + // First non-pinned keeps name, rest get numeric suffix + for i := 1; i < len(group); i++ { + if group[i].Pinned { + continue + } + group[i].GoName = group[i].GoName + strconv.Itoa(i+1) + } + return len(group) > 1 +} + +// contentTypeSuffix returns a short suffix for a media type. +func contentTypeSuffix(ct string) string { + if ct == "" { + return "" + } + ct = strings.ToLower(ct) + switch { + case strings.Contains(ct, "json"): + return "JSON" + case strings.Contains(ct, "xml"): + return "XML" + case strings.Contains(ct, "form"): + return "Form" + case strings.Contains(ct, "text"): + return "Text" + case strings.Contains(ct, "octet"): + return "Binary" + case strings.Contains(ct, "yaml"): + return "YAML" + default: + return mediaTypeToCamelCase(ct) + } +} diff --git a/pkg/codegen/resolve_names_test.go b/pkg/codegen/resolve_names_test.go new file mode 100644 index 0000000000..806eaf6740 --- /dev/null +++ b/pkg/codegen/resolve_names_test.go @@ -0,0 +1,379 @@ +package codegen + +import ( + "testing" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/stretchr/testify/assert" +) + +func TestResolveNames_NoCollisions(t *testing.T) { + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Pet"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Pet", + }, + { + Path: SchemaPath{"components", "schemas", "Owner"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Owner", + }, + } + + result := ResolveNames(schemas) + + assert.Equal(t, "Pet", result["components/schemas/Pet"]) + assert.Equal(t, "Owner", result["components/schemas/Owner"]) +} + +func TestResolveNames_Issue200_CrossSectionCollisions(t *testing.T) { + // "Bar" appears in schemas, parameters, responses, requestBodies, headers + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Bar"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Bar", + }, + { + Path: SchemaPath{"components", "parameters", "Bar"}, + Context: ContextComponentParameter, + Schema: &openapi3.Schema{}, + ComponentName: "Bar", + }, + { + Path: SchemaPath{"components", "responses", "Bar", "content", "application/json"}, + Context: ContextComponentResponse, + Schema: &openapi3.Schema{}, + ComponentName: "Bar", + ContentType: "application/json", + }, + { + Path: SchemaPath{"components", "requestBodies", "Bar", "content", "application/json"}, + Context: ContextComponentRequestBody, + Schema: &openapi3.Schema{}, + ComponentName: "Bar", + ContentType: "application/json", + }, + { + Path: SchemaPath{"components", "headers", "Bar"}, + Context: ContextComponentHeader, + Schema: &openapi3.Schema{}, + ComponentName: "Bar", + }, + } + + result := ResolveNames(schemas) + + // Component schema is privileged — keeps bare name + assert.Equal(t, "Bar", result["components/schemas/Bar"]) + // Others get context suffixes + assert.Equal(t, "BarParameter", result["components/parameters/Bar"]) + assert.Equal(t, "BarResponse", result["components/responses/Bar/content/application/json"]) + assert.Equal(t, "BarRequestBody", result["components/requestBodies/Bar/content/application/json"]) + assert.Equal(t, "BarHeader", result["components/headers/Bar"]) +} + +func TestResolveNames_Issue1474_ClientWrapperCollision(t *testing.T) { + // Schema named "CreateChatCompletionResponse" collides with + // client wrapper for operation "createChatCompletion" which + // would generate "CreateChatCompletionResponse". + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "CreateChatCompletionResponse"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "CreateChatCompletionResponse", + }, + { + Path: SchemaPath{"paths", "/chat/completions", "POST", "x-client-response-wrapper"}, + Context: ContextClientResponseWrapper, + OperationID: "createChatCompletion", + }, + } + + result := ResolveNames(schemas) + + // Component schema is privileged — keeps its name + assert.Equal(t, "CreateChatCompletionResponse", result["components/schemas/CreateChatCompletionResponse"]) + // Client wrapper gets a suffix to avoid collision + wrapperName := result["paths//chat/completions/POST/x-client-response-wrapper"] + assert.NotEqual(t, "CreateChatCompletionResponse", wrapperName, + "client wrapper should not collide with component schema") + assert.Contains(t, wrapperName, "Response", + "client wrapper should still contain 'Response'") +} + +func TestResolveNames_PrivilegedComponentSchema(t *testing.T) { + // When exactly one collision member is a component schema, + // it keeps the bare name + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Foo"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + }, + { + Path: SchemaPath{"components", "parameters", "Foo"}, + Context: ContextComponentParameter, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + }, + } + + result := ResolveNames(schemas) + + assert.Equal(t, "Foo", result["components/schemas/Foo"]) + assert.Equal(t, "FooParameter", result["components/parameters/Foo"]) +} + +func TestResolveNames_NoComponentSchema_AllGetSuffixes(t *testing.T) { + // When no member is a component schema, all get suffixed + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "parameters", "Foo"}, + Context: ContextComponentParameter, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + }, + { + Path: SchemaPath{"components", "responses", "Foo", "content", "application/json"}, + Context: ContextComponentResponse, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + ContentType: "application/json", + }, + } + + result := ResolveNames(schemas) + + assert.Equal(t, "FooParameter", result["components/parameters/Foo"]) + assert.Equal(t, "FooResponse", result["components/responses/Foo/content/application/json"]) +} + +func TestResolveNames_NumericFallback(t *testing.T) { + // Two schemas with same context that can't be disambiguated + // by context suffix (both are component schemas) + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Foo"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + }, + { + // Hypothetical: same candidate name from a different path + // This shouldn't normally happen with real specs, but tests the fallback + Path: SchemaPath{"components", "schemas", "foo"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "foo", + }, + } + + result := ResolveNames(schemas) + + names := make(map[string]bool) + for _, name := range result { + names[name] = true + } + // Both should have unique names + assert.Len(t, names, 2, "should have two unique names") +} + +func TestResolveNames_MultipleJsonContentTypes(t *testing.T) { + // "Order" appears in schemas and requestBodies. The requestBody has + // 3 content types that all contain "json" and map to the same "JSON" + // suffix. The global phase approach should prevent oscillation between + // context suffix and content type suffix, letting numeric fallback resolve. + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Order"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Order", + }, + { + Path: SchemaPath{"components", "requestBodies", "Order", "content", "application/json"}, + Context: ContextComponentRequestBody, + Schema: &openapi3.Schema{}, + ComponentName: "Order", + ContentType: "application/json", + }, + { + Path: SchemaPath{"components", "requestBodies", "Order", "content", "application/merge-patch+json"}, + Context: ContextComponentRequestBody, + Schema: &openapi3.Schema{}, + ComponentName: "Order", + ContentType: "application/merge-patch+json", + }, + { + Path: SchemaPath{"components", "requestBodies", "Order", "content", "application/json-patch+json"}, + Context: ContextComponentRequestBody, + Schema: &openapi3.Schema{}, + ComponentName: "Order", + ContentType: "application/json-patch+json", + }, + } + + result := ResolveNames(schemas) + + // Component schema keeps bare name + assert.Equal(t, "Order", result["components/schemas/Order"]) + + // All 3 requestBody types must have unique names + names := make(map[string]bool) + for _, name := range result { + names[name] = true + } + assert.Len(t, names, 4, "all 4 types should have unique names") + + // The first requestBody should get RequestBody+JSON suffixes + assert.Equal(t, "OrderRequestBodyJSON", + result["components/requestBodies/Order/content/application/json"]) + + // The remaining two collide on OrderRequestBodyJSON and get numeric fallback + jsonPatchName := result["components/requestBodies/Order/content/application/json-patch+json"] + mergePatchName := result["components/requestBodies/Order/content/application/merge-patch+json"] + assert.NotEqual(t, jsonPatchName, mergePatchName, + "json-patch and merge-patch types must have different names") + assert.Contains(t, jsonPatchName, "OrderRequestBodyJSON") + assert.Contains(t, mergePatchName, "OrderRequestBodyJSON") +} + +func TestResolveNames_XGoNamePinned_Schema(t *testing.T) { + // Pattern K: schema "Renamer" has x-go-name="SpecialName" which collides + // with nothing, but a response also named "Renamer" should keep its + // normal resolved name. The schema is pinned. + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Renamer"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Renamer", + GoNameOverride: "SpecialName", + }, + { + Path: SchemaPath{"components", "responses", "Renamer", "content", "application/json"}, + Context: ContextComponentResponse, + Schema: &openapi3.Schema{}, + ComponentName: "Renamer", + ContentType: "application/json", + }, + } + + result := ResolveNames(schemas) + + // Schema pinned to SpecialName + assert.Equal(t, "SpecialName", result["components/schemas/Renamer"]) + // Response keeps bare name since there's no collision with "Renamer" + assert.Equal(t, "Renamer", result["components/responses/Renamer/content/application/json"]) +} + +func TestResolveNames_XGoNamePinned_Response(t *testing.T) { + // Pattern L: response "Outcome" has x-go-name="OutcomeResult" and + // schema also named "Outcome". The response is pinned as "OutcomeResult", + // so the schema keeps "Outcome" (no collision). + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Outcome"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Outcome", + }, + { + Path: SchemaPath{"components", "responses", "Outcome", "content", "application/json"}, + Context: ContextComponentResponse, + Schema: &openapi3.Schema{}, + ComponentName: "Outcome", + ContentType: "application/json", + GoNameOverride: "OutcomeResult", + }, + } + + result := ResolveNames(schemas) + + // Schema keeps bare name + assert.Equal(t, "Outcome", result["components/schemas/Outcome"]) + // Response pinned to OutcomeResult + assert.Equal(t, "OutcomeResult", result["components/responses/Outcome/content/application/json"]) +} + +func TestResolveNames_XGoNamePinned_RequestBody(t *testing.T) { + // Pattern M: requestBody "Payload" has x-go-name="PayloadBody" and + // schema also named "Payload". The requestBody is pinned. + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Payload"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Payload", + }, + { + Path: SchemaPath{"components", "requestBodies", "Payload", "content", "application/json"}, + Context: ContextComponentRequestBody, + Schema: &openapi3.Schema{}, + ComponentName: "Payload", + ContentType: "application/json", + GoNameOverride: "PayloadBody", + }, + } + + result := ResolveNames(schemas) + + // Schema keeps bare name + assert.Equal(t, "Payload", result["components/schemas/Payload"]) + // RequestBody pinned to PayloadBody + assert.Equal(t, "PayloadBody", result["components/requestBodies/Payload/content/application/json"]) +} + +func TestResolveNames_PinnedNotModifiedByStrategies(t *testing.T) { + // Pinned name "Foo" vs non-pinned parameter "Foo" → parameter gets suffixed + schemas := []*GatheredSchema{ + { + Path: SchemaPath{"components", "schemas", "Foo"}, + Context: ContextComponentSchema, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + GoNameOverride: "Foo", + }, + { + Path: SchemaPath{"components", "parameters", "Foo"}, + Context: ContextComponentParameter, + Schema: &openapi3.Schema{}, + ComponentName: "Foo", + }, + } + + result := ResolveNames(schemas) + + // Pinned schema stays as "Foo" + assert.Equal(t, "Foo", result["components/schemas/Foo"]) + // Parameter gets suffixed to resolve collision + assert.Equal(t, "FooParameter", result["components/parameters/Foo"]) +} + +func TestContentTypeSuffix(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {"application/json", "JSON"}, + {"application/xml", "XML"}, + {"application/x-www-form-urlencoded", "Form"}, + {"text/plain", "Text"}, + {"application/octet-stream", "Binary"}, + {"application/yaml", "YAML"}, + {"", ""}, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + assert.Equal(t, tt.expected, contentTypeSuffix(tt.input)) + }) + } +} diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 067d03955d..ff72d23b6b 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -40,21 +40,8 @@ type Schema struct { // The original OpenAPIv3 Schema. OAPISchema *openapi3.Schema - DefinedComp ComponentType // Indicates which component section defined this type } -// ComponentType is used to keep track of where a given schema came from, in order -// to perform type name collision resolution. -type ComponentType int - -const ( - ComponentTypeSchema = iota - ComponentTypeParameter - ComponentTypeRequestBody - ComponentTypeResponse - ComponentTypeHeader -) - func (s Schema) IsRef() bool { return s.RefType != "" } @@ -325,7 +312,6 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { Description: schema.Description, OAPISchema: schema, SkipOptionalPointer: skipOptionalPointer, - DefinedComp: ComponentTypeSchema, } // AllOf is interesting, and useful. It's the union of a number of other @@ -835,9 +821,7 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) { // We can process the schema through the generic schema processor if param.Schema != nil { - schema, err := GenerateGoSchema(param.Schema, path) - schema.DefinedComp = ComponentTypeParameter - return schema, err + return GenerateGoSchema(param.Schema, path) } // At this point, we have a content type. We know how to deal with @@ -847,7 +831,6 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) { return Schema{ GoType: "string", Description: StringToGoComment(param.Description), - DefinedComp: ComponentTypeParameter, }, nil } @@ -858,14 +841,11 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) { return Schema{ GoType: "string", Description: StringToGoComment(param.Description), - DefinedComp: ComponentTypeParameter, }, nil } // For json, we go through the standard schema mechanism - schema, err := GenerateGoSchema(mt.Schema, path) - schema.DefinedComp = ComponentTypeParameter - return schema, err + return GenerateGoSchema(mt.Schema, path) } func generateUnion(outSchema *Schema, elements openapi3.SchemaRefs, discriminator *openapi3.Discriminator, path []string) error { diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 64caf12828..e4d932116a 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -259,8 +259,13 @@ func buildUnmarshalCaseStrict(typeDefinition ResponseTypeDefinition, caseAction return caseKey, caseClause } -// genResponseTypeName creates the name of generated response types (given the operationID): +// genResponseTypeName creates the name of generated response types (given the operationID). +// It first checks if the multi-pass name resolver has assigned a name for this +// wrapper type (which would happen if the default name collides with a schema type). func genResponseTypeName(operationID string) string { + if name, ok := globalState.resolvedClientWrapperNames[operationID]; ok { + return name + } return fmt.Sprintf("%s%s", UppercaseFirstCharacter(operationID), responseTypeSuffix) } diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index 549d5cffa3..adfeb7c89f 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -474,6 +474,20 @@ func refPathToGoTypeSelf(refPath string, local bool) (string, error) { return "", fmt.Errorf("unexpected reference depth: %d for ref: %s local: %t", depth, refPath, local) } + // When multi-pass name resolution is active, the resolved name takes + // precedence over the spec-given name. For a $ref like + // #/components/schemas/Thing, we pass the section ("schemas") and + // name ("Thing") to resolvedNameForComponent, which looks up the + // final Go type name assigned by the collision resolver. + // Note: the resolver prioritizes component schemas — if a schema and + // a response both claim "Thing", the component schema keeps the original + // name and the response becomes "ThingResponse". + if depth == 4 && pathParts[0] == "#" && pathParts[1] == "components" { + if resolved := resolvedNameForComponent(pathParts[2], pathParts[3]); resolved != "" { + return resolved, nil + } + } + // Schemas may have been renamed locally, so look up the actual name in // the spec. name, err := findSchemaNameByRefPath(refPath, globalState.spec) @@ -1124,86 +1138,3 @@ func isAdditionalPropertiesExplicitFalse(s *openapi3.Schema) bool { func sliceContains[E comparable](s []E, v E) bool { return slices.Contains(s, v) } - -// FixDuplicateTypeNames renames duplicate type names. -func FixDuplicateTypeNames(typeDefs []TypeDefinition) []TypeDefinition { - if !hasDuplicatedTypeNames(typeDefs) { - return typeDefs - } - - // try to fix duplicate type names with their definition section - typeDefs = fixDuplicateTypeNamesWithCompName(typeDefs) - if !hasDuplicatedTypeNames(typeDefs) { - return typeDefs - } - - const maxIter = 100 - for i := 0; i < maxIter && hasDuplicatedTypeNames(typeDefs); i++ { - typeDefs = fixDuplicateTypeNamesDupCounts(typeDefs) - } - - if hasDuplicatedTypeNames(typeDefs) { - panic("too much duplicate type names") - } - - return typeDefs -} - -func hasDuplicatedTypeNames(typeDefs []TypeDefinition) bool { - dupCheck := make(map[string]int, len(typeDefs)) - - for _, d := range typeDefs { - dupCheck[d.TypeName]++ - - if dupCheck[d.TypeName] != 1 { - return true - } - } - - return false -} - -func fixDuplicateTypeNamesWithCompName(typeDefs []TypeDefinition) []TypeDefinition { - dupCheck := make(map[string]int, len(typeDefs)) - deDup := make([]TypeDefinition, len(typeDefs)) - - for i, d := range typeDefs { - dupCheck[d.TypeName]++ - - if dupCheck[d.TypeName] != 1 { - switch d.Schema.DefinedComp { - case ComponentTypeSchema: - d.TypeName += "Schema" - case ComponentTypeParameter: - d.TypeName += "Parameter" - case ComponentTypeRequestBody: - d.TypeName += "RequestBody" - case ComponentTypeResponse: - d.TypeName += "Response" - case ComponentTypeHeader: - d.TypeName += "Header" - } - } - - deDup[i] = d - } - - return deDup -} - -func fixDuplicateTypeNamesDupCounts(typeDefs []TypeDefinition) []TypeDefinition { - dupCheck := make(map[string]int, len(typeDefs)) - deDup := make([]TypeDefinition, len(typeDefs)) - - for i, d := range typeDefs { - dupCheck[d.TypeName]++ - - if dupCheck[d.TypeName] != 1 { - d.TypeName = d.TypeName + strconv.Itoa(dupCheck[d.TypeName]) - } - - deDup[i] = d - } - - return deDup -} From c966b373e95f4385b33e04424b08d70757466895 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 2 Mar 2026 06:16:57 -0800 Subject: [PATCH 02/62] fix: use RequiresNilCheck for all params (#2263) PR #2237 fixed query parameters to use RequiresNilCheck instead of HasOptionalPointer for nil-check guards, but the same bug remained in the header and cookie parameter sections of client.tmpl. This caused optional array params (e.g. []string) to be sent even when nil, because prefer-skip-optional-pointer removes the pointer wrapper and HasOptionalPointer returns false, skipping the nil check entirely. Co-authored-by: Claude Opus 4.6 --- internal/test/issues/issue-2238/config.yaml | 7 + internal/test/issues/issue-2238/generate.go | 3 + .../test/issues/issue-2238/issue2238.gen.go | 262 ++++++++++++++++++ .../test/issues/issue-2238/issue2238_test.go | 56 ++++ internal/test/issues/issue-2238/openapi.yaml | 22 ++ pkg/codegen/templates/client.tmpl | 8 +- 6 files changed, 354 insertions(+), 4 deletions(-) create mode 100644 internal/test/issues/issue-2238/config.yaml create mode 100644 internal/test/issues/issue-2238/generate.go create mode 100644 internal/test/issues/issue-2238/issue2238.gen.go create mode 100644 internal/test/issues/issue-2238/issue2238_test.go create mode 100644 internal/test/issues/issue-2238/openapi.yaml diff --git a/internal/test/issues/issue-2238/config.yaml b/internal/test/issues/issue-2238/config.yaml new file mode 100644 index 0000000000..cbb78b8d30 --- /dev/null +++ b/internal/test/issues/issue-2238/config.yaml @@ -0,0 +1,7 @@ +package: issue2238 +generate: + models: true + client: true +output-options: + prefer-skip-optional-pointer: true +output: issue2238.gen.go diff --git a/internal/test/issues/issue-2238/generate.go b/internal/test/issues/issue-2238/generate.go new file mode 100644 index 0000000000..5c10773236 --- /dev/null +++ b/internal/test/issues/issue-2238/generate.go @@ -0,0 +1,3 @@ +package issue2238 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml openapi.yaml diff --git a/internal/test/issues/issue-2238/issue2238.gen.go b/internal/test/issues/issue-2238/issue2238.gen.go new file mode 100644 index 0000000000..81f395ddfa --- /dev/null +++ b/internal/test/issues/issue-2238/issue2238.gen.go @@ -0,0 +1,262 @@ +// Package issue2238 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 issue2238 + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// GetTestParams defines parameters for GetTest. +type GetTestParams struct { + XTags []string `json:"X-Tags,omitempty"` + Tags []string `form:"tags,omitempty" json:"tags,omitempty"` +} + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetTest request + GetTest(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetTest(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetTestRequest(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) +} + +// NewGetTestRequest generates requests for GetTest +func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/test") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + if params.XTags != nil { + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithOptions("simple", false, "X-Tags", params.XTags, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Tags", headerParam0) + } + + } + + if params != nil { + + if params.Tags != nil { + var cookieParam0 string + + cookieParam0, err = runtime.StyleParamWithOptions("simple", true, "tags", params.Tags, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + cookie0 := &http.Cookie{ + Name: "tags", + Value: cookieParam0, + } + req.AddCookie(cookie0) + } + } + return req, nil +} + +func (c *Client) 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 *Client) 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 { + // GetTestWithResponse request + GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) +} + +type GetTestResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetTestResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetTestResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetTestWithResponse request returning *GetTestResponse +func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { + rsp, err := c.GetTest(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetTestResponse(rsp) +} + +// ParseGetTestResponse parses an HTTP response from a GetTestWithResponse call +func ParseGetTestResponse(rsp *http.Response) (*GetTestResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetTestResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/issues/issue-2238/issue2238_test.go b/internal/test/issues/issue-2238/issue2238_test.go new file mode 100644 index 0000000000..8c399efa52 --- /dev/null +++ b/internal/test/issues/issue-2238/issue2238_test.go @@ -0,0 +1,56 @@ +package issue2238 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewGetTestRequest(t *testing.T) { + t.Run("nil header array param is not sent", func(t *testing.T) { + params := GetTestParams{ + XTags: nil, + } + + req, err := NewGetTestRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.Empty(t, req.Header.Values("X-Tags")) + }) + + t.Run("non-nil header array param is sent", func(t *testing.T) { + params := GetTestParams{ + XTags: []string{"a", "b"}, + } + + req, err := NewGetTestRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.NotEmpty(t, req.Header.Values("X-Tags")) + }) + + t.Run("nil cookie array param is not sent", func(t *testing.T) { + params := GetTestParams{ + Tags: nil, + } + + req, err := NewGetTestRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.Empty(t, req.Cookies()) + }) + + t.Run("non-nil cookie array param is sent", func(t *testing.T) { + params := GetTestParams{ + Tags: []string{"a", "b"}, + } + + req, err := NewGetTestRequest("https://localhost", ¶ms) + require.NoError(t, err) + + cookies := req.Cookies() + require.Len(t, cookies, 1) + assert.Equal(t, "tags", cookies[0].Name) + }) +} diff --git a/internal/test/issues/issue-2238/openapi.yaml b/internal/test/issues/issue-2238/openapi.yaml new file mode 100644 index 0000000000..4e026542ac --- /dev/null +++ b/internal/test/issues/issue-2238/openapi.yaml @@ -0,0 +1,22 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Issue 2238 +paths: + /test: + get: + parameters: + - name: X-Tags + in: header + schema: + type: array + items: + type: string + required: false + - name: tags + in: cookie + schema: + type: array + items: + type: string + required: false diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl index 27085038dc..24410dfae6 100644 --- a/pkg/codegen/templates/client.tmpl +++ b/pkg/codegen/templates/client.tmpl @@ -236,7 +236,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr {{ if .HeaderParams }} if params != nil { {{range $paramIdx, $param := .HeaderParams}} - {{if .HasOptionalPointer}} if params.{{.GoName}} != nil { {{end}} + {{if .RequiresNilCheck}} if params.{{.GoName}} != nil { {{end}} var headerParam{{$paramIdx}} string {{if .IsPassThrough}} headerParam{{$paramIdx}} = {{if .HasOptionalPointer}}*{{end}}params.{{.GoName}} @@ -256,7 +256,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr } {{end}} req.Header.Set("{{.ParamName}}", headerParam{{$paramIdx}}) - {{if .HasOptionalPointer}}}{{end}} + {{if .RequiresNilCheck}}}{{end}} {{end}} } {{- end }}{{/* if .HeaderParams */}} @@ -264,7 +264,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr {{ if .CookieParams }} if params != nil { {{range $paramIdx, $param := .CookieParams}} - {{if .HasOptionalPointer}} if params.{{.GoName}} != nil { {{end}} + {{if .RequiresNilCheck}} if params.{{.GoName}} != nil { {{end}} var cookieParam{{$paramIdx}} string {{if .IsPassThrough}} cookieParam{{$paramIdx}} = {{if .HasOptionalPointer}}*{{end}}params.{{.GoName}} @@ -288,7 +288,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr Value:cookieParam{{$paramIdx}}, } req.AddCookie(cookie{{$paramIdx}}) - {{if .HasOptionalPointer}}}{{end}} + {{if .RequiresNilCheck}}}{{end}} {{ end -}} } {{- end }}{{/* if .CookieParams */}} From 863c6ea3f57ed8ec5c0826e1733aa4cb134a55d3 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 2 Mar 2026 06:18:51 -0800 Subject: [PATCH 03/62] Update all dependencies to Go 1.24 (#2264) * chore: require go 1.24 as minimum version across all modules Bump all go.mod files from go 1.22.5 to go 1.24 and normalize any go 1.24.0 to go 1.24 for consistency. Co-Authored-By: Claude Opus 4.6 * chore: remove inner go.mod files that existed only for go 1.24 requirement Now that all modules require go 1.24, these inner modules are no longer needed as separate modules. Their packages are absorbed by the parent modules (internal/test and examples), which now include the fiber dependencies directly. Removed inner modules: - internal/test/strict-server/fiber/ - internal/test/issues/issue1469/ - internal/test/issues/issue-1529/strict-fiber/ - examples/minimal-server/stdhttp-go-tool/ - examples/minimal-server/fiber/ - examples/extensions/xomitzero/ - examples/petstore-expanded/fiber/ - examples/output-options/preferskipoptionalpointerwithomitzero/ Co-Authored-By: Claude Opus 4.6 * chore: update dependencies to latest go 1.24-compatible versions Run go get for all direct dependencies across all modules, constrained to go 1.24 via GOTOOLCHAIN=go1.24.4 to avoid pulling in deps that require go 1.25. Notable updates: - gin v1.10.1 -> v1.11.0 (v1.12.0 requires go 1.25) - iris v12.2.6 -> v12.2.11 - echo v4.11.4/v4.12.0 -> v4.15.1 - chi v5.0.10 -> v5.2.5 - golang.org/x/tools v0.30.0 -> v0.42.0 - golang.org/x/mod v0.23.0 -> v0.33.0 - golang.org/x/text v0.20.0 -> v0.34.0 Pinned speakeasy-api/jsonpath at v0.6.0 across all modules due to v0.6.1+ removing the pkg/overlay package that openapi-overlay tests depend on. Pinned dprotaso/go-yit at the pre-yaml/v4 version as the newer version switches to go.yaml.in/yaml/v4 which is incompatible with vmware-labs/yaml-jsonpath. Co-Authored-By: Claude Opus 4.6 * update readme * ci: skip Go 1.22 and 1.23 in CI matrix Now that all modules require go 1.24, exclude older versions from the CI build/test/tidy/generate matrix via the excluding_versions input on the reusable workflow. Co-Authored-By: Claude Opus 4.6 * chore: remove Go version guards from child module Makefiles Now that go 1.24 is the minimum version, the execute-if-go-122/124 guards are always true. Simplify the Makefiles to run commands directly. Co-Authored-By: Claude Opus 4.6 * chore: update deprecated code Remove usage of deprecated middleware.Logger() from Echo examples and tests. This was deprecated in Echo v4.15.1 in favor of middleware.RequestLogger or middleware.RequestLoggerWithConfig. Since these calls only added request logging for debugging convenience, they are removed rather than replaced. Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- .github/workflows/ci.yml | 1 + README.md | 25 -- examples/authenticated-api/echo/main.go | 2 - examples/authenticated-api/stdhttp/Makefile | 31 +- examples/authenticated-api/stdhttp/go.mod | 34 +-- examples/authenticated-api/stdhttp/go.sum | 118 +++----- examples/extensions/xomitzero/Makefile | 36 --- examples/extensions/xomitzero/go.mod | 35 --- examples/extensions/xomitzero/go.sum | 173 ----------- examples/go.mod | 107 +++---- examples/go.sum | 274 +++++++++--------- examples/minimal-server/fiber/Makefile | 36 --- examples/minimal-server/fiber/go.mod | 44 --- examples/minimal-server/fiber/go.sum | 198 ------------- .../minimal-server/stdhttp-go-tool/Makefile | 36 --- .../minimal-server/stdhttp-go-tool/go.mod | 31 -- .../minimal-server/stdhttp-go-tool/go.sum | 173 ----------- examples/minimal-server/stdhttp/Makefile | 31 +- examples/minimal-server/stdhttp/go.mod | 20 +- examples/minimal-server/stdhttp/go.sum | 63 ++-- .../Makefile | 36 --- .../go.mod | 35 --- .../go.sum | 173 ----------- examples/petstore-expanded/echo/petstore.go | 3 - .../petstore-expanded/echo/petstore_test.go | 4 - examples/petstore-expanded/fiber/Makefile | 36 --- examples/petstore-expanded/fiber/go.mod | 53 ---- examples/petstore-expanded/fiber/go.sum | 212 -------------- examples/petstore-expanded/stdhttp/Makefile | 31 +- examples/petstore-expanded/stdhttp/go.mod | 28 +- examples/petstore-expanded/stdhttp/go.sum | 71 +++-- go.mod | 24 +- go.sum | 59 ++-- internal/test/go.mod | 102 ++++--- internal/test/go.sum | 242 ++++++++-------- .../issues/issue-1529/strict-fiber/Makefile | 36 --- .../issues/issue-1529/strict-fiber/go.mod | 46 --- .../issues/issue-1529/strict-fiber/go.sum | 198 ------------- .../issue-1529/strict-fiber/issue1529.gen.go | 2 +- internal/test/issues/issue1469/Makefile | 36 --- internal/test/issues/issue1469/go.mod | 49 ---- internal/test/issues/issue1469/go.sum | 198 ------------- internal/test/parameters/parameters_test.go | 4 - internal/test/strict-server/fiber/Makefile | 36 --- internal/test/strict-server/fiber/go.mod | 55 ---- internal/test/strict-server/fiber/go.sum | 210 -------------- internal/test/strict-server/stdhttp/Makefile | 31 +- internal/test/strict-server/stdhttp/go.mod | 26 +- internal/test/strict-server/stdhttp/go.sum | 71 +++-- 49 files changed, 632 insertions(+), 2943 deletions(-) delete mode 100644 examples/extensions/xomitzero/Makefile delete mode 100644 examples/extensions/xomitzero/go.mod delete mode 100644 examples/extensions/xomitzero/go.sum delete mode 100644 examples/minimal-server/fiber/Makefile delete mode 100644 examples/minimal-server/fiber/go.mod delete mode 100644 examples/minimal-server/fiber/go.sum delete mode 100644 examples/minimal-server/stdhttp-go-tool/Makefile delete mode 100644 examples/minimal-server/stdhttp-go-tool/go.mod delete mode 100644 examples/minimal-server/stdhttp-go-tool/go.sum delete mode 100644 examples/output-options/preferskipoptionalpointerwithomitzero/Makefile delete mode 100644 examples/output-options/preferskipoptionalpointerwithomitzero/go.mod delete mode 100644 examples/output-options/preferskipoptionalpointerwithomitzero/go.sum delete mode 100644 examples/petstore-expanded/fiber/Makefile delete mode 100644 examples/petstore-expanded/fiber/go.mod delete mode 100644 examples/petstore-expanded/fiber/go.sum delete mode 100644 internal/test/issues/issue-1529/strict-fiber/Makefile delete mode 100644 internal/test/issues/issue-1529/strict-fiber/go.mod delete mode 100644 internal/test/issues/issue-1529/strict-fiber/go.sum delete mode 100644 internal/test/issues/issue1469/Makefile delete mode 100644 internal/test/issues/issue1469/go.mod delete mode 100644 internal/test/issues/issue1469/go.sum delete mode 100644 internal/test/strict-server/fiber/Makefile delete mode 100644 internal/test/strict-server/fiber/go.mod delete mode 100644 internal/test/strict-server/fiber/go.sum diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a010b440e..2d5e0a1c6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ jobs: build: uses: oapi-codegen/actions/.github/workflows/ci.yml@75566d848d25021f137594c947f26171094fb511 # v0.5.0 with: + excluding_versions: '["1.22", "1.23"]' lint_versions: '["1.25"]' build-binaries: diff --git a/README.md b/README.md index 321cc42679..da058e65a5 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,6 @@ go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest ## Install -### For Go 1.24+ - It is recommended to follow [the `go tool` support available from Go 1.24+](https://www.jvt.me/posts/2025/01/27/go-tools-124/) for managing the dependency of `oapi-codegen` alongside your core application. To do this, you run `go get -tool`: @@ -59,29 +57,6 @@ From there, each invocation of `oapi-codegen` would be used like so: //go:generate go tool oapi-codegen -config cfg.yaml ../../api.yaml ``` -### Prior to Go 1.24 - -It is recommended to follow [the `tools.go` pattern](https://www.jvt.me/posts/2022/06/15/go-tools-dependency-management/) for managing the dependency of `oapi-codegen` alongside your core application. - -This would give you a `tools/tools.go`: - -```go -//go:build tools -// +build tools - -package main - -import ( - _ "github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen" -) -``` - -Then, each invocation of `oapi-codegen` would be used like so: - -```go -//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml ../../api.yaml -``` - Alternatively, you can install it as a binary with: ```sh diff --git a/examples/authenticated-api/echo/main.go b/examples/authenticated-api/echo/main.go index 905f8d8aeb..dc4b42c45a 100644 --- a/examples/authenticated-api/echo/main.go +++ b/examples/authenticated-api/echo/main.go @@ -6,7 +6,6 @@ import ( "net" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" "github.com/oapi-codegen/oapi-codegen/v2/examples/authenticated-api/echo/api" "github.com/oapi-codegen/oapi-codegen/v2/examples/authenticated-api/echo/server" ) @@ -28,7 +27,6 @@ func main() { if err != nil { log.Fatalln("error creating middleware:", err) } - e.Use(middleware.Logger()) e.Use(mw...) svr := server.NewServer() diff --git a/examples/authenticated-api/stdhttp/Makefile b/examples/authenticated-api/stdhttp/Makefile index 48fe768e30..5ec0edd058 100644 --- a/examples/authenticated-api/stdhttp/Makefile +++ b/examples/authenticated-api/stdhttp/Makefile @@ -1,36 +1,17 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-122 -@{ \ -if [[ 22 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.22, which this module requires$(RESET)"; \ -fi \ -} -endef - lint: - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./...) + $(GOBIN)/golangci-lint run ./... lint-ci: - - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m generate: - $(call execute-if-go-122,go generate ./...) + go generate ./... test: - $(call execute-if-go-122,go test -cover ./...) + go test -cover ./... tidy: - $(call execute-if-go-122,go mod tidy) + go mod tidy tidy-ci: - $(call execute-if-go-122,tidied -verbose) + tidied -verbose diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index 3a2081ba2a..64d200dc01 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -1,25 +1,25 @@ module github.com/oapi-codegen/oapi-codegen/v2/examples/authenticated-api/stdhttp -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( github.com/getkin/kin-openapi v0.133.0 - github.com/lestrrat-go/jwx v1.2.29 - github.com/oapi-codegen/nethttp-middleware v1.0.2 + github.com/lestrrat-go/jwx v1.2.31 + github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect @@ -27,22 +27,22 @@ require ( github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index a6e130e447..372e7efe62 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -2,11 +2,11 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -15,15 +15,17 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -46,13 +48,11 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= @@ -61,20 +61,20 @@ github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZ github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= -github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= +github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= +github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/nethttp-middleware v1.0.2 h1:A5tfAcKJhWIbIPnlQH+l/DtfVE1i5TFgPlQAiW+l1vQ= -github.com/oapi-codegen/nethttp-middleware v1.0.2/go.mod h1:DfDalonSO+eRQ3RTb8kYoWZByCCPFRxm9WKq1UbY0E4= +github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe513tvJpiMJjypVPA= +github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= @@ -97,71 +97,51 @@ github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -176,36 +156,21 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -219,9 +184,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/extensions/xomitzero/Makefile b/examples/extensions/xomitzero/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/examples/extensions/xomitzero/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/examples/extensions/xomitzero/go.mod b/examples/extensions/xomitzero/go.mod deleted file mode 100644 index 6b1e3678b8..0000000000 --- a/examples/extensions/xomitzero/go.mod +++ /dev/null @@ -1,35 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/examples/extensions/xomitzero - -go 1.24 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ - -require ( - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/stretchr/testify v1.11.1 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/examples/extensions/xomitzero/go.sum b/examples/extensions/xomitzero/go.sum deleted file mode 100644 index fdce2066b1..0000000000 --- a/examples/extensions/xomitzero/go.sum +++ /dev/null @@ -1,173 +0,0 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/go.mod b/examples/go.mod index 04cb27ccd2..0b92bb2e87 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,27 +1,29 @@ module github.com/oapi-codegen/oapi-codegen/v2/examples -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../ require ( github.com/getkin/kin-openapi v0.133.0 - github.com/gin-gonic/gin v1.10.1 - github.com/go-chi/chi/v5 v5.0.10 + github.com/gin-gonic/gin v1.11.0 + github.com/go-chi/chi/v5 v5.2.5 + github.com/gofiber/fiber/v2 v2.52.12 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 - github.com/labstack/echo/v4 v4.12.0 - github.com/lestrrat-go/jwx v1.2.26 + github.com/kataras/iris/v12 v12.2.11 + github.com/labstack/echo/v4 v4.15.1 + github.com/lestrrat-go/jwx v1.2.31 github.com/oapi-codegen/echo-middleware v1.0.2 + github.com/oapi-codegen/fiber-middleware v1.0.2 github.com/oapi-codegen/gin-middleware v1.0.2 github.com/oapi-codegen/iris-middleware v1.0.5 - github.com/oapi-codegen/nethttp-middleware v1.0.2 + github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 - github.com/oapi-codegen/testutil v1.0.0 + github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 - golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 + golang.org/x/lint v0.0.0-20241112194109-818c5a804067 ) require ( @@ -33,84 +35,91 @@ require ( github.com/andybalholm/brotli v1.1.0 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bytedance/sonic v1.11.6 // indirect - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.20.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect + github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/iris-contrib/schema v0.0.6 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/pio v0.0.12 // indirect + github.com/kataras/blocks v0.0.8 // indirect + github.com/kataras/golog v0.1.11 // indirect + github.com/kataras/pio v0.0.13 // indirect github.com/kataras/sitemap v0.0.6 // indirect github.com/kataras/tunnel v0.0.4 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.1 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/microcosm-cc/bluemonday v1.0.26 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/closestmatch v2.1.0+incompatible // indirect github.com/sirupsen/logrus v1.9.1 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/tdewolff/minify/v2 v2.20.19 // indirect + github.com/tdewolff/parse/v2 v2.7.12 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/yosssi/ace v0.0.5 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.33.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.30.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index 7a8759d76b..180de2d19d 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -20,23 +20,21 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= -github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= -github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -48,39 +46,43 @@ github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0H github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= -github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug= +github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= -github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/gofiber/fiber/v2 v2.52.12 h1:0LdToKclcPOj8PktUdIKo9BUohjjwfnQl42Dhw8/WUw= +github.com/gofiber/fiber/v2 v2.52.12/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -92,14 +94,14 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 h1:4gjrh/PN2MuWCCElk8/I4OCKRKWCCo2zEct3VKCbibU= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -110,8 +112,8 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= @@ -125,61 +127,57 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= +github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM= +github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg= +github.com/kataras/golog v0.1.11 h1:dGkcCVsIpqiAMWTlebn/ZULHxFvfG4K43LF1cNWSh20= +github.com/kataras/golog v0.1.11/go.mod h1:mAkt1vbPowFUuUGvexyQ5NFW6djEgGyxQBIARJ0AH4A= +github.com/kataras/iris/v12 v12.2.11 h1:sGgo43rMPfzDft8rjVhPs6L3qDJy3TbBrMD/zGL1pzk= +github.com/kataras/iris/v12 v12.2.11/go.mod h1:uMAeX8OqG9vqdhyrIPv8Lajo/wXTtAF43wchP9WHt2w= +github.com/kataras/pio v0.0.13 h1:x0rXVX0fviDTXOOLOmr4MUxOabu1InVSTu5itF8CXCM= +github.com/kataras/pio v0.0.13/go.mod h1:k3HNuSw+eJ8Pm2lA4lRhg3DiCjVgHlP8hmXApSej3oM= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= -github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/echo/v4 v4.15.1 h1:S9keusg26gZpjMmPqB5hOEvNKnmd1lNmcHrbbH2lnFs= +github.com/labstack/echo/v4 v4.15.1/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= -github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= -github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= +github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= +github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -189,22 +187,26 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/echo-middleware v1.0.2 h1:oNBqiE7jd/9bfGNk/bpbX2nqWrtPc+LL4Boya8Wl81U= github.com/oapi-codegen/echo-middleware v1.0.2/go.mod h1:5J6MFcGqrpWLXpbKGZtRPZViLIHyyyUHlkqg6dT2R4E= +github.com/oapi-codegen/fiber-middleware v1.0.2 h1:f4KPdjyRTYh2GyAv9wsDP+Q9akOND17wuMSbmMwDkJI= +github.com/oapi-codegen/fiber-middleware v1.0.2/go.mod h1:+lGj+802Ajp/+fQG9d8t1SuYP8r7lnOc6wnOwwRArYg= github.com/oapi-codegen/gin-middleware v1.0.2 h1:/H99UzvHQAUxXK8pzdcGAZgjCVeXdFDAUUWaJT0k0eI= github.com/oapi-codegen/gin-middleware v1.0.2/go.mod h1:2HJDQjH8jzK2/k/VKcWl+/T41H7ai2bKa6dN3AA2GpA= github.com/oapi-codegen/iris-middleware v1.0.5 h1:eO33pCvapaf1Xa0esEP0PYcdqPZSeq1eze4mamhT5hU= github.com/oapi-codegen/iris-middleware v1.0.5/go.mod h1:/ysgvbjWyhfDAouIeUOjzIv+zsXfaIXlAQrsOU9/Kyo= -github.com/oapi-codegen/nethttp-middleware v1.0.2 h1:A5tfAcKJhWIbIPnlQH+l/DtfVE1i5TFgPlQAiW+l1vQ= -github.com/oapi-codegen/nethttp-middleware v1.0.2/go.mod h1:DfDalonSO+eRQ3RTb8kYoWZByCCPFRxm9WKq1UbY0E4= +github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe513tvJpiMJjypVPA= +github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= -github.com/oapi-codegen/testutil v1.0.0 h1:1GI2IiMMLh2vDHr1OkNacaYU/VaApKdcmfgl4aeXAa8= -github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= +github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= +github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -221,16 +223,22 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= @@ -244,13 +252,12 @@ github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -260,32 +267,35 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= +github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= +github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= +github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -302,49 +312,41 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -361,38 +363,27 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -405,13 +396,12 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -429,5 +419,3 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/examples/minimal-server/fiber/Makefile b/examples/minimal-server/fiber/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/examples/minimal-server/fiber/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/examples/minimal-server/fiber/go.mod b/examples/minimal-server/fiber/go.mod deleted file mode 100644 index 58abd2fa35..0000000000 --- a/examples/minimal-server/fiber/go.mod +++ /dev/null @@ -1,44 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/fiber - -go 1.24.0 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require github.com/gofiber/fiber/v2 v2.52.11 - -require ( - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/examples/minimal-server/fiber/go.sum b/examples/minimal-server/fiber/go.sum deleted file mode 100644 index e2954b1efc..0000000000 --- a/examples/minimal-server/fiber/go.sum +++ /dev/null @@ -1,198 +0,0 @@ -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= -github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/minimal-server/stdhttp-go-tool/Makefile b/examples/minimal-server/stdhttp-go-tool/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/examples/minimal-server/stdhttp-go-tool/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/examples/minimal-server/stdhttp-go-tool/go.mod b/examples/minimal-server/stdhttp-go-tool/go.mod deleted file mode 100644 index de08a03c54..0000000000 --- a/examples/minimal-server/stdhttp-go-tool/go.mod +++ /dev/null @@ -1,31 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/stdhttp-go-tool - -go 1.24 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require ( - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/examples/minimal-server/stdhttp-go-tool/go.sum b/examples/minimal-server/stdhttp-go-tool/go.sum deleted file mode 100644 index fdce2066b1..0000000000 --- a/examples/minimal-server/stdhttp-go-tool/go.sum +++ /dev/null @@ -1,173 +0,0 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/minimal-server/stdhttp/Makefile b/examples/minimal-server/stdhttp/Makefile index 48fe768e30..5ec0edd058 100644 --- a/examples/minimal-server/stdhttp/Makefile +++ b/examples/minimal-server/stdhttp/Makefile @@ -1,36 +1,17 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-122 -@{ \ -if [[ 22 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.22, which this module requires$(RESET)"; \ -fi \ -} -endef - lint: - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./...) + $(GOBIN)/golangci-lint run ./... lint-ci: - - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m generate: - $(call execute-if-go-122,go generate ./...) + go generate ./... test: - $(call execute-if-go-122,go test -cover ./...) + go test -cover ./... tidy: - $(call execute-if-go-122,go mod tidy) + go mod tidy tidy-ci: - $(call execute-if-go-122,tidied -verbose) + tidied -verbose diff --git a/examples/minimal-server/stdhttp/go.mod b/examples/minimal-server/stdhttp/go.mod index f1ef1ba7b4..98ad587fc4 100644 --- a/examples/minimal-server/stdhttp/go.mod +++ b/examples/minimal-server/stdhttp/go.mod @@ -1,6 +1,6 @@ module github.com/oapi-codegen/oapi-codegen/v2/examples/minimal-server/stdhttp -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ @@ -9,22 +9,22 @@ require github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-0000000000 require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/minimal-server/stdhttp/go.sum b/examples/minimal-server/stdhttp/go.sum index fdce2066b1..e5ac6ef8cc 100644 --- a/examples/minimal-server/stdhttp/go.sum +++ b/examples/minimal-server/stdhttp/go.sum @@ -2,8 +2,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -12,10 +13,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -39,15 +42,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -71,16 +72,15 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -90,15 +90,15 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -106,13 +106,13 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -127,21 +127,21 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -155,9 +155,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/output-options/preferskipoptionalpointerwithomitzero/Makefile b/examples/output-options/preferskipoptionalpointerwithomitzero/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/examples/output-options/preferskipoptionalpointerwithomitzero/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/examples/output-options/preferskipoptionalpointerwithomitzero/go.mod b/examples/output-options/preferskipoptionalpointerwithomitzero/go.mod deleted file mode 100644 index 6f75dac750..0000000000 --- a/examples/output-options/preferskipoptionalpointerwithomitzero/go.mod +++ /dev/null @@ -1,35 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/examples/output-options/preferskipoptionalpointerwithomitzero - -go 1.24 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ - -require ( - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/stretchr/testify v1.11.1 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/examples/output-options/preferskipoptionalpointerwithomitzero/go.sum b/examples/output-options/preferskipoptionalpointerwithomitzero/go.sum deleted file mode 100644 index fdce2066b1..0000000000 --- a/examples/output-options/preferskipoptionalpointerwithomitzero/go.sum +++ /dev/null @@ -1,173 +0,0 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/petstore-expanded/echo/petstore.go b/examples/petstore-expanded/echo/petstore.go index 5ea0250507..7287d2b354 100644 --- a/examples/petstore-expanded/echo/petstore.go +++ b/examples/petstore-expanded/echo/petstore.go @@ -12,7 +12,6 @@ import ( "os" "github.com/labstack/echo/v4" - echomiddleware "github.com/labstack/echo/v4/middleware" middleware "github.com/oapi-codegen/echo-middleware" "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo/api" ) @@ -36,8 +35,6 @@ func main() { // This is how you set up a basic Echo router e := echo.New() - // Log all requests - e.Use(echomiddleware.Logger()) // Use our validation middleware to check all requests against the // OpenAPI schema. e.Use(middleware.OapiRequestValidator(swagger)) diff --git a/examples/petstore-expanded/echo/petstore_test.go b/examples/petstore-expanded/echo/petstore_test.go index 5fc058da94..092e6238e8 100644 --- a/examples/petstore-expanded/echo/petstore_test.go +++ b/examples/petstore-expanded/echo/petstore_test.go @@ -20,7 +20,6 @@ import ( "testing" "github.com/labstack/echo/v4" - echoMiddleware "github.com/labstack/echo/v4/middleware" middleware "github.com/oapi-codegen/echo-middleware" "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo/api" "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo/api/models" @@ -48,9 +47,6 @@ func TestPetStore(t *testing.T) { // Validate requests against the OpenAPI spec e.Use(middleware.OapiRequestValidator(swagger)) - // Log requests - e.Use(echoMiddleware.Logger()) - // We register the autogenerated boilerplate and bind our PetStore to this // echo router. api.RegisterHandlers(e, store) diff --git a/examples/petstore-expanded/fiber/Makefile b/examples/petstore-expanded/fiber/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/examples/petstore-expanded/fiber/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/examples/petstore-expanded/fiber/go.mod b/examples/petstore-expanded/fiber/go.mod deleted file mode 100644 index 848ae29799..0000000000 --- a/examples/petstore-expanded/fiber/go.mod +++ /dev/null @@ -1,53 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/fiber - -go 1.24.0 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require ( - github.com/getkin/kin-openapi v0.133.0 - github.com/gofiber/fiber/v2 v2.52.11 - github.com/oapi-codegen/fiber-middleware v1.0.2 - github.com/oapi-codegen/runtime v1.2.0 - github.com/stretchr/testify v1.11.1 -) - -require ( - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/examples/petstore-expanded/fiber/go.sum b/examples/petstore-expanded/fiber/go.sum deleted file mode 100644 index 4d328b9424..0000000000 --- a/examples/petstore-expanded/fiber/go.sum +++ /dev/null @@ -1,212 +0,0 @@ -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= -github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/fiber-middleware v1.0.2 h1:f4KPdjyRTYh2GyAv9wsDP+Q9akOND17wuMSbmMwDkJI= -github.com/oapi-codegen/fiber-middleware v1.0.2/go.mod h1:+lGj+802Ajp/+fQG9d8t1SuYP8r7lnOc6wnOwwRArYg= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/petstore-expanded/stdhttp/Makefile b/examples/petstore-expanded/stdhttp/Makefile index 48fe768e30..5ec0edd058 100644 --- a/examples/petstore-expanded/stdhttp/Makefile +++ b/examples/petstore-expanded/stdhttp/Makefile @@ -1,36 +1,17 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-122 -@{ \ -if [[ 22 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.22, which this module requires$(RESET)"; \ -fi \ -} -endef - lint: - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./...) + $(GOBIN)/golangci-lint run ./... lint-ci: - - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m generate: - $(call execute-if-go-122,go generate ./...) + go generate ./... test: - $(call execute-if-go-122,go test -cover ./...) + go test -cover ./... tidy: - $(call execute-if-go-122,go mod tidy) + go mod tidy tidy-ci: - $(call execute-if-go-122,tidied -verbose) + tidied -verbose diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index cd3edaec36..3922deb19e 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -1,41 +1,41 @@ module github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/stdhttp -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( github.com/getkin/kin-openapi v0.133.0 - github.com/oapi-codegen/nethttp-middleware v1.0.2 + github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 - github.com/oapi-codegen/testutil v1.0.0 + github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/google/uuid v1.5.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.30.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index 33f9b11fbb..677ca72245 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -6,8 +6,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -16,10 +17,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -48,26 +51,24 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/nethttp-middleware v1.0.2 h1:A5tfAcKJhWIbIPnlQH+l/DtfVE1i5TFgPlQAiW+l1vQ= -github.com/oapi-codegen/nethttp-middleware v1.0.2/go.mod h1:DfDalonSO+eRQ3RTb8kYoWZByCCPFRxm9WKq1UbY0E4= +github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe513tvJpiMJjypVPA= +github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= -github.com/oapi-codegen/testutil v1.0.0 h1:1GI2IiMMLh2vDHr1OkNacaYU/VaApKdcmfgl4aeXAa8= -github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= +github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= +github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -86,16 +87,15 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -107,15 +107,15 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -123,13 +123,13 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -144,21 +144,21 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -172,9 +172,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/go.mod b/go.mod index 12e391a6ee..ce84f98d4e 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,35 @@ module github.com/oapi-codegen/oapi-codegen/v2 -go 1.22.5 +go 1.24.3 + +toolchain go1.24.4 require ( github.com/getkin/kin-openapi v0.133.0 github.com/speakeasy-api/openapi-overlay v0.10.2 github.com/stretchr/testify v1.11.1 - golang.org/x/mod v0.23.0 - golang.org/x/text v0.20.0 - golang.org/x/tools v0.30.0 + golang.org/x/mod v0.33.0 + golang.org/x/text v0.34.0 + golang.org/x/tools v0.42.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/sync v0.11.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/sync v0.19.0 // indirect ) diff --git a/go.sum b/go.sum index fdce2066b1..8e99a7a7fd 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -12,10 +13,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -39,15 +42,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -71,10 +72,9 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= @@ -90,15 +90,15 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -106,13 +106,13 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -127,21 +127,21 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -155,9 +155,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/internal/test/go.mod b/internal/test/go.mod index f027d757f8..6f70f67ca3 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -1,21 +1,22 @@ module github.com/oapi-codegen/oapi-codegen/v2/internal/test -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../ require ( github.com/getkin/kin-openapi v0.133.0 - github.com/gin-gonic/gin v1.10.1 - github.com/go-chi/chi/v5 v5.0.10 - github.com/google/uuid v1.5.0 + github.com/gin-gonic/gin v1.11.0 + github.com/go-chi/chi/v5 v5.2.5 + github.com/gofiber/fiber/v2 v2.52.12 + github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 - github.com/labstack/echo/v4 v4.11.4 - github.com/oapi-codegen/nullable v1.0.1 + github.com/kataras/iris/v12 v12.2.11 + github.com/labstack/echo/v4 v4.15.1 + github.com/oapi-codegen/nullable v1.1.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 - github.com/oapi-codegen/testutil v1.0.0 + github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v2 v2.4.0 ) @@ -26,81 +27,88 @@ require ( github.com/CloudyKit/jet/v6 v6.2.0 // indirect github.com/Joker/jade v1.1.3 // indirect github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bytedance/sonic v1.11.6 // indirect - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect + github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/iris-contrib/schema v0.0.6 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/pio v0.0.12 // indirect + github.com/kataras/blocks v0.0.8 // indirect + github.com/kataras/golog v0.1.11 // indirect + github.com/kataras/pio v0.0.13 // indirect github.com/kataras/sitemap v0.0.6 // indirect github.com/kataras/tunnel v0.0.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/microcosm-cc/bluemonday v1.0.26 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/closestmatch v2.1.0+incompatible // indirect github.com/sirupsen/logrus v1.9.1 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect + github.com/tdewolff/minify/v2 v2.20.19 // indirect + github.com/tdewolff/parse/v2 v2.7.12 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/yosssi/ace v0.0.5 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.33.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.30.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/test/go.sum b/internal/test/go.sum index 2d726a40f9..d4d3ba66ee 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -13,27 +13,26 @@ github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= -github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= -github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -45,30 +44,32 @@ github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0H github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= -github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug= +github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= -github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -76,8 +77,10 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/gofiber/fiber/v2 v2.52.12 h1:0LdToKclcPOj8PktUdIKo9BUohjjwfnQl42Dhw8/WUw= +github.com/gofiber/fiber/v2 v2.52.12/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -89,26 +92,26 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 h1:4gjrh/PN2MuWCCElk8/I4OCKRKWCCo2zEct3VKCbibU= +github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= @@ -122,48 +125,44 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= +github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM= +github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg= +github.com/kataras/golog v0.1.11 h1:dGkcCVsIpqiAMWTlebn/ZULHxFvfG4K43LF1cNWSh20= +github.com/kataras/golog v0.1.11/go.mod h1:mAkt1vbPowFUuUGvexyQ5NFW6djEgGyxQBIARJ0AH4A= +github.com/kataras/iris/v12 v12.2.11 h1:sGgo43rMPfzDft8rjVhPs6L3qDJy3TbBrMD/zGL1pzk= +github.com/kataras/iris/v12 v12.2.11/go.mod h1:uMAeX8OqG9vqdhyrIPv8Lajo/wXTtAF43wchP9WHt2w= +github.com/kataras/pio v0.0.13 h1:x0rXVX0fviDTXOOLOmr4MUxOabu1InVSTu5itF8CXCM= +github.com/kataras/pio v0.0.13/go.mod h1:k3HNuSw+eJ8Pm2lA4lRhg3DiCjVgHlP8hmXApSej3oM= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= -github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= +github.com/labstack/echo/v4 v4.15.1 h1:S9keusg26gZpjMmPqB5hOEvNKnmd1lNmcHrbbH2lnFs= +github.com/labstack/echo/v4 v4.15.1/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -173,16 +172,18 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/nullable v1.0.1 h1:/g+R1Kl1qVYhXlVTg+YT4UnHeYqW+cDh9rfzr+pAV/0= -github.com/oapi-codegen/nullable v1.0.1/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= +github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= -github.com/oapi-codegen/testutil v1.0.0 h1:1GI2IiMMLh2vDHr1OkNacaYU/VaApKdcmfgl4aeXAa8= -github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= +github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= +github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -199,14 +200,19 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= @@ -220,8 +226,8 @@ github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -232,37 +238,39 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= +github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= +github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= +github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -279,18 +287,21 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -300,14 +311,14 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -325,27 +336,25 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -358,13 +367,12 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -382,5 +390,3 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/internal/test/issues/issue-1529/strict-fiber/Makefile b/internal/test/issues/issue-1529/strict-fiber/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/internal/test/issues/issue-1529/strict-fiber/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/internal/test/issues/issue-1529/strict-fiber/go.mod b/internal/test/issues/issue-1529/strict-fiber/go.mod deleted file mode 100644 index 5e881be269..0000000000 --- a/internal/test/issues/issue-1529/strict-fiber/go.mod +++ /dev/null @@ -1,46 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1529/strict-fiber - -go 1.24.0 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../../ - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require ( - github.com/getkin/kin-openapi v0.133.0 - github.com/gofiber/fiber/v2 v2.52.11 -) - -require ( - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/internal/test/issues/issue-1529/strict-fiber/go.sum b/internal/test/issues/issue-1529/strict-fiber/go.sum deleted file mode 100644 index e2954b1efc..0000000000 --- a/internal/test/issues/issue-1529/strict-fiber/go.sum +++ /dev/null @@ -1,198 +0,0 @@ -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= -github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index 4d6ab516f5..e1324845b6 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -1,6 +1,6 @@ // Package issue1529 provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.1 DO NOT EDIT. +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package issue1529 import ( diff --git a/internal/test/issues/issue1469/Makefile b/internal/test/issues/issue1469/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/internal/test/issues/issue1469/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/internal/test/issues/issue1469/go.mod b/internal/test/issues/issue1469/go.mod deleted file mode 100644 index fbd28f728a..0000000000 --- a/internal/test/issues/issue1469/go.mod +++ /dev/null @@ -1,49 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue1469 - -go 1.24.0 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require ( - github.com/gofiber/fiber/v2 v2.52.11 - github.com/stretchr/testify v1.11.1 -) - -require ( - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/internal/test/issues/issue1469/go.sum b/internal/test/issues/issue1469/go.sum deleted file mode 100644 index e2954b1efc..0000000000 --- a/internal/test/issues/issue1469/go.sum +++ /dev/null @@ -1,198 +0,0 @@ -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= -github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/test/parameters/parameters_test.go b/internal/test/parameters/parameters_test.go index 29f6680e02..0635301dfa 100644 --- a/internal/test/parameters/parameters_test.go +++ b/internal/test/parameters/parameters_test.go @@ -9,7 +9,6 @@ import ( "github.com/oapi-codegen/testutil" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -243,7 +242,6 @@ func (t *testServer) EnumParams(ctx echo.Context, params EnumParamsParams) error func TestParameterBinding(t *testing.T) { var ts testServer e := echo.New() - e.Use(middleware.Logger()) RegisterHandlers(e, &ts) expectedObject := Object{ @@ -527,7 +525,6 @@ func doRequest(t *testing.T, e *echo.Echo, code int, req *http.Request) *httptes func TestClientPathParams(t *testing.T) { var ts testServer e := echo.New() - e.Use(middleware.Logger()) RegisterHandlers(e, &ts) server := "http://example.com" @@ -651,7 +648,6 @@ func TestClientPathParams(t *testing.T) { func TestClientQueryParams(t *testing.T) { var ts testServer e := echo.New() - e.Use(middleware.Logger()) RegisterHandlers(e, &ts) server := "http://example.com" diff --git a/internal/test/strict-server/fiber/Makefile b/internal/test/strict-server/fiber/Makefile deleted file mode 100644 index bb37d63394..0000000000 --- a/internal/test/strict-server/fiber/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-124 -@{ \ -if [[ 24 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.24, which this module requires$(RESET)"; \ -fi \ -} -endef - -lint: - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./...) - -lint-ci: - - $(call execute-if-go-124,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) - -generate: - $(call execute-if-go-124,go generate ./...) - -test: - $(call execute-if-go-124,go test -cover ./...) - -tidy: - $(call execute-if-go-124,go mod tidy) - -tidy-ci: - $(call execute-if-go-124,tidied -verbose) diff --git a/internal/test/strict-server/fiber/go.mod b/internal/test/strict-server/fiber/go.mod deleted file mode 100644 index a5442edf9d..0000000000 --- a/internal/test/strict-server/fiber/go.mod +++ /dev/null @@ -1,55 +0,0 @@ -module github.com/oapi-codegen/oapi-codegen/v2/internal/test/strict-server/fiber - -go 1.24.0 - -replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ - -replace github.com/oapi-codegen/oapi-codegen/v2/internal/test => ../.. - -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - -require ( - github.com/getkin/kin-openapi v0.133.0 - github.com/gofiber/fiber/v2 v2.52.11 - github.com/oapi-codegen/oapi-codegen/v2/internal/test v0.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 - github.com/oapi-codegen/testutil v1.0.0 - github.com/stretchr/testify v1.11.1 -) - -require ( - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect - github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/internal/test/strict-server/fiber/go.sum b/internal/test/strict-server/fiber/go.sum deleted file mode 100644 index 0d990d7990..0000000000 --- a/internal/test/strict-server/fiber/go.sum +++ /dev/null @@ -1,210 +0,0 @@ -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= -github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= -github.com/oapi-codegen/testutil v1.0.0 h1:1GI2IiMMLh2vDHr1OkNacaYU/VaApKdcmfgl4aeXAa8= -github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/test/strict-server/stdhttp/Makefile b/internal/test/strict-server/stdhttp/Makefile index 48fe768e30..5ec0edd058 100644 --- a/internal/test/strict-server/stdhttp/Makefile +++ b/internal/test/strict-server/stdhttp/Makefile @@ -1,36 +1,17 @@ -SHELL:=/bin/bash - -YELLOW := \e[0;33m -RESET := \e[0;0m - -GOVER := $(shell go env GOVERSION) -GOMINOR := $(shell bash -c "cut -f1 -d' ' <<< \"$(GOVER)\" | cut -f2 -d.") - -define execute-if-go-122 -@{ \ -if [[ 22 -le $(GOMINOR) ]]; then \ - $1; \ -else \ - echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.22, which this module requires$(RESET)"; \ -fi \ -} -endef - lint: - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./...) + $(GOBIN)/golangci-lint run ./... lint-ci: - - $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m) + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m generate: - $(call execute-if-go-122,go generate ./...) + go generate ./... test: - $(call execute-if-go-122,go test -cover ./...) + go test -cover ./... tidy: - $(call execute-if-go-122,go mod tidy) + go mod tidy tidy-ci: - $(call execute-if-go-122,tidied -verbose) + tidied -verbose diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 4e0463b0c5..19a1b1cfb5 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -1,6 +1,6 @@ module github.com/oapi-codegen/oapi-codegen/v2/internal/test/strict-server/stdhttp -go 1.22.5 +go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ @@ -17,26 +17,26 @@ require ( require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.30.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 57cd609934..4680d9a4bb 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -6,8 +6,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -16,10 +17,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -39,22 +42,20 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -82,16 +83,15 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -99,19 +99,19 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -119,13 +119,13 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -140,21 +140,21 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -168,9 +168,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= From f459fd71fe71c475979bcda62181b14c2f4ee853 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Mon, 2 Mar 2026 09:02:20 +0000 Subject: [PATCH 04/62] docs: note that JSON Schema should be pinned Plus add Renovate configuration to update this in the future. --- README.md | 4 +++- renovate.json | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da058e65a5..aa4dc860ee 100644 --- a/README.md +++ b/README.md @@ -112,11 +112,13 @@ For full details of what is supported, it's worth checking out [the GoDoc for `c We also have [a JSON Schema](configuration-schema.json) that can be used by IDEs/editors with the Language Server Protocol (LSP) to perform intelligent suggestions, i.e.: ```yaml -# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json +# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/v2.6.0/configuration-schema.json package: api # ... ``` +Note that it's recommended to pin to a specific version of the configuration schema, so it matches the version of `oapi-codegen` you're using. For instance, if you're using [Renovate](https://docs.renovatebot.com/), you can [have Renovate automagically update this version for you](https://www.jvt.me/posts/2026/03/01/oapi-codegen-config-renovate/). + ### Backwards compatibility Although we strive to retain backwards compatibility - as a project that's using a stable API per SemVer - there are sometimes opportunities we must take to fix a bug that could cause a breaking change for [people relying upon the behaviour](https://xkcd.com/1172/). diff --git a/renovate.json b/renovate.json index 3af37f23db..8ac4d6e63c 100644 --- a/renovate.json +++ b/renovate.json @@ -69,5 +69,18 @@ "executionMode": "branch" } } + ], + "customManagers": [ + { + "customType": "regex", + "managerFilePatterns": [ + "README.md" + ], + "matchStrings": [ + "# yaml-language-server: \\$schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/(?[^/]+)/configuration-schema.json" + ], + "depNameTemplate": "github.com/oapi-codegen/oapi-codegen/v2", + "datasourceTemplate": "go" + } ] } From 717f4621327e3cab4705837c0045a7b8e6965e3c Mon Sep 17 00:00:00 2001 From: Jinu Thankachan <7960767+jinuthankachan@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:54:57 +0530 Subject: [PATCH 05/62] feat: Support echo/v5 (#2188) * feat: server code generation for echo/v5 * feat/echov5-codegen (#6) * server code generation for echo/v5 * does not include: - strict-server for echo/v5 - middlewares for echo/v5 * fix: rename PathParam to Param for echo/v5 * fix: missing parts for strict server (#9) * fix: add the missing strict server generation * Clean up router imports Instead of hardcoding each router's framework and strict middleware imports directly in imports.tmpl with per-router conditional blocks, compute them in Go code via GenerateOptions.RouterImports() and pass them to the template as RouterImports. The template now uses a single range loop over .RouterImports, making it straightforward to add new routers without touching the template. Co-Authored-By: Claude Opus 4.6 * Add petstore-expanded/echo-v5 example Echo v5 version of the petstore-expanded example, in its own Go module (go 1.25.0) to avoid bumping the Go version of the shared examples module. Key differences from the echo (v4) example: - *echo.Context (pointer) instead of echo.Context (interface) - echo.NewHTTPError(code, message) takes exactly two args - No HTTPError.Internal field - EchoRouter returns echo.RouteInfo instead of *echo.Route - log.Fatal(e.Start(...)) instead of e.Logger.Fatal(...) Includes an inline OpenAPI request validation middleware (middleware/) adapted from echo-middleware for echo v5, since no published echo-v5 middleware package exists yet. Models and server stubs are placeholders until the codegen circular dependency for go:generate in isolated modules is resolved. Co-Authored-By: Claude Opus 4.6 * fix: skip echo-v5 example on Go < 1.25 The echo-v5 example requires Go 1.25+ (for echo/v5). When CI runs with GOTOOLCHAIN=local on Go 1.24, the module refuses to build. Add a Go version guard to the Makefile so all targets skip gracefully with an informational message on older Go versions. Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: DanDagadita Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.6 --- cmd/oapi-codegen/oapi-codegen.go | 2 + configuration-schema.json | 16 +- examples/petstore-expanded/echo-v5/Makefile | 30 +++ .../echo-v5/api/models.cfg.yaml | 5 + .../echo-v5/api/models/models.gen.go | 46 ++++ .../echo-v5/api/petstore-server.gen.go | 247 ++++++++++++++++++ .../petstore-expanded/echo-v5/api/petstore.go | 146 +++++++++++ .../echo-v5/api/server.cfg.yaml | 9 + examples/petstore-expanded/echo-v5/go.mod | 42 +++ examples/petstore-expanded/echo-v5/go.sum | 191 ++++++++++++++ .../echo-v5/middleware/middleware.go | 226 ++++++++++++++++ .../petstore-expanded/echo-v5/petstore.go | 48 ++++ .../echo-v5/petstore_test.go | 152 +++++++++++ .../petstore-expanded/echo-v5/tools/tools.go | 8 + pkg/codegen/codegen.go | 17 ++ pkg/codegen/configuration.go | 53 ++++ pkg/codegen/operations.go | 9 + .../templates/echo/v5/echo-interface.tmpl | 7 + .../templates/echo/v5/echo-register.tmpl | 33 +++ .../templates/echo/v5/echo-wrappers.tmpl | 131 ++++++++++ pkg/codegen/templates/imports.tmpl | 14 +- .../templates/strict/strict-echo5.tmpl | 97 +++++++ 22 files changed, 1509 insertions(+), 20 deletions(-) create mode 100644 examples/petstore-expanded/echo-v5/Makefile create mode 100644 examples/petstore-expanded/echo-v5/api/models.cfg.yaml create mode 100644 examples/petstore-expanded/echo-v5/api/models/models.gen.go create mode 100644 examples/petstore-expanded/echo-v5/api/petstore-server.gen.go create mode 100644 examples/petstore-expanded/echo-v5/api/petstore.go create mode 100644 examples/petstore-expanded/echo-v5/api/server.cfg.yaml create mode 100644 examples/petstore-expanded/echo-v5/go.mod create mode 100644 examples/petstore-expanded/echo-v5/go.sum create mode 100644 examples/petstore-expanded/echo-v5/middleware/middleware.go create mode 100644 examples/petstore-expanded/echo-v5/petstore.go create mode 100644 examples/petstore-expanded/echo-v5/petstore_test.go create mode 100644 examples/petstore-expanded/echo-v5/tools/tools.go create mode 100644 pkg/codegen/templates/echo/v5/echo-interface.tmpl create mode 100644 pkg/codegen/templates/echo/v5/echo-register.tmpl create mode 100644 pkg/codegen/templates/echo/v5/echo-wrappers.tmpl create mode 100644 pkg/codegen/templates/strict/strict-echo5.tmpl diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go index a3e43498c4..088821f5da 100644 --- a/cmd/oapi-codegen/oapi-codegen.go +++ b/cmd/oapi-codegen/oapi-codegen.go @@ -512,6 +512,8 @@ func generationTargets(cfg *codegen.Configuration, targets []string) error { opts.FiberServer = true case "server", "echo-server", "echo": opts.EchoServer = true + case "echo5", "echo5-server": + opts.Echo5Server = true case "gin", "gin-server": opts.GinServer = true case "gorilla", "gorilla-server": diff --git a/configuration-schema.json b/configuration-schema.json index a81feefa3c..d25061e31b 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -29,6 +29,10 @@ "type": "boolean", "description": "EchoServer specifies whether to generate echo server boilerplate" }, + "echo5-server": { + "type": "boolean", + "description": "Echo5Server specifies whether to generate echo v5 server boilerplate" + }, "gin-server": { "type": "boolean", "description": "GinServer specifies whether to generate gin server boilerplate" @@ -197,9 +201,7 @@ "description": "DisableTypeAliasesForType allows defining which OpenAPI `type`s will explicitly not use type aliases", "items": { "type": "string", - "enum": [ - "array" - ] + "enum": ["array"] } }, "name-normalizer": { @@ -226,9 +228,7 @@ "default": true } }, - "required": [ - "path" - ] + "required": ["path"] }, "yaml-tags": { "type": "boolean", @@ -299,9 +299,7 @@ "type": "string" } }, - "required": [ - "package" - ] + "required": ["package"] }, "description": "AdditionalImports defines any additional Go imports to add to the generated code" }, diff --git a/examples/petstore-expanded/echo-v5/Makefile b/examples/petstore-expanded/echo-v5/Makefile new file mode 100644 index 0000000000..7eb1896df1 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/Makefile @@ -0,0 +1,30 @@ +# This module requires Go 1.25+ (for echo/v5). Skip gracefully on older versions. +GO_VERSION := $(shell go version | sed 's/.*go\([0-9]*\)\.\([0-9]*\).*/\1\2/') +GO_125_OR_LATER := $(shell [ "$(GO_VERSION)" -ge 125 ] 2>/dev/null && echo yes || echo no) + +ifeq ($(GO_125_OR_LATER),yes) + +lint: + $(GOBIN)/golangci-lint run ./... + +lint-ci: + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m + +generate: + go generate ./... + +test: + go test -cover ./... + +tidy: + go mod tidy + +tidy-ci: + tidied -verbose + +else + +lint generate test tidy lint-ci tidy-ci: + @echo "Skipping echo-v5 example: requires Go 1.25+ (found $(shell go version))" + +endif diff --git a/examples/petstore-expanded/echo-v5/api/models.cfg.yaml b/examples/petstore-expanded/echo-v5/api/models.cfg.yaml new file mode 100644 index 0000000000..46b5e629c3 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/api/models.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: models +generate: + models: true +output: models/models.gen.go diff --git a/examples/petstore-expanded/echo-v5/api/models/models.gen.go b/examples/petstore-expanded/echo-v5/api/models/models.gen.go new file mode 100644 index 0000000000..0945e02abb --- /dev/null +++ b/examples/petstore-expanded/echo-v5/api/models/models.gen.go @@ -0,0 +1,46 @@ +// Package models 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 models + +// Error defines model for Error. +type Error struct { + // Code Error code + Code int32 `json:"code"` + + // Message Error message + Message string `json:"message"` +} + +// NewPet defines model for NewPet. +type NewPet struct { + // Name Name of the pet + Name string `json:"name"` + + // Tag Type of the pet + Tag *string `json:"tag,omitempty"` +} + +// Pet defines model for Pet. +type Pet struct { + // Id Unique id of the pet + Id int64 `json:"id"` + + // Name Name of the pet + Name string `json:"name"` + + // Tag Type of the pet + Tag *string `json:"tag,omitempty"` +} + +// FindPetsParams defines parameters for FindPets. +type FindPetsParams struct { + // Tags tags to filter by + Tags *[]string `form:"tags,omitempty" json:"tags,omitempty"` + + // Limit maximum number of results to return + Limit *int32 `form:"limit,omitempty" json:"limit,omitempty"` +} + +// AddPetJSONRequestBody defines body for AddPet for application/json ContentType. +type AddPetJSONRequestBody = NewPet diff --git a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go new file mode 100644 index 0000000000..c99d14e424 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go @@ -0,0 +1,247 @@ +// Package api 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 api + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/labstack/echo/v5" + . "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api/models" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + // Returns all pets + // (GET /pets) + FindPets(ctx *echo.Context, params FindPetsParams) error + // Creates a new pet + // (POST /pets) + AddPet(ctx *echo.Context) error + // Deletes a pet by ID + // (DELETE /pets/{id}) + DeletePet(ctx *echo.Context, id int64) error + // Returns a pet by ID + // (GET /pets/{id}) + FindPetByID(ctx *echo.Context, id int64) error +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +// FindPets converts echo context to params. +func (w *ServerInterfaceWrapper) FindPets(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params FindPetsParams + // ------------- Optional query parameter "tags" ------------- + + err = runtime.BindQueryParameter("form", true, false, "tags", ctx.QueryParams(), ¶ms.Tags) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tags: %s", err)) + } + + // ------------- Optional query parameter "limit" ------------- + + err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.FindPets(ctx, params) + return err +} + +// AddPet converts echo context to params. +func (w *ServerInterfaceWrapper) AddPet(ctx *echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.AddPet(ctx) + return err +} + +// DeletePet converts echo context to params. +func (w *ServerInterfaceWrapper) DeletePet(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int64 + + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.DeletePet(ctx, id) + return err +} + +// FindPetByID converts echo context to params. +func (w *ServerInterfaceWrapper) FindPetByID(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int64 + + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.FindPetByID(ctx, id) + return err +} + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithBaseURL(router, si, "") +} + +// Registers handlers, and prepends BaseURL to the paths, so that the paths +// can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.GET(baseURL+"/pets", wrapper.FindPets) + router.POST(baseURL+"/pets", wrapper.AddPet) + router.DELETE(baseURL+"/pets/:id", wrapper.DeletePet) + router.GET(baseURL+"/pets/:id", wrapper.FindPetByID) + +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", + "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", + "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", + "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", + "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", + "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", + "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", + "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", + "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", + "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", + "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", + "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", + "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", + "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", + "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", + "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", + "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", + "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", + "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", + "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", + "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", + "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", + "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", + "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", + "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", + "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", + "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", + "97cAAAD//ykDnxlaEgAA", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/examples/petstore-expanded/echo-v5/api/petstore.go b/examples/petstore-expanded/echo-v5/api/petstore.go new file mode 100644 index 0000000000..6313eec228 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/api/petstore.go @@ -0,0 +1,146 @@ +// Copyright 2019 DeepMap, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=models.cfg.yaml ../../petstore-expanded.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../../petstore-expanded.yaml + +package api + +import ( + "fmt" + "net/http" + "sync" + + "github.com/labstack/echo/v5" + "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api/models" +) + +type PetStore struct { + Pets map[int64]models.Pet + NextId int64 + Lock sync.Mutex +} + +func NewPetStore() *PetStore { + return &PetStore{ + Pets: make(map[int64]models.Pet), + NextId: 1000, + } +} + +// sendPetStoreError wraps sending of an error in the Error format, and +// handling the failure to marshal that. +func sendPetStoreError(ctx *echo.Context, code int, message string) error { + petErr := models.Error{ + Code: int32(code), + Message: message, + } + err := ctx.JSON(code, petErr) + return err +} + +// FindPets implements all the handlers in the ServerInterface +func (p *PetStore) FindPets(ctx *echo.Context, params models.FindPetsParams) error { + p.Lock.Lock() + defer p.Lock.Unlock() + + var result []models.Pet + + for _, pet := range p.Pets { + if params.Tags != nil { + // If we have tags, filter pets by tag + for _, t := range *params.Tags { + if pet.Tag != nil && (*pet.Tag == t) { + result = append(result, pet) + } + } + } else { + // Add all pets if we're not filtering + result = append(result, pet) + } + + if params.Limit != nil { + l := int(*params.Limit) + if len(result) >= l { + // We're at the limit + break + } + } + } + return ctx.JSON(http.StatusOK, result) +} + +func (p *PetStore) AddPet(ctx *echo.Context) error { + // We expect a NewPet object in the request body. + var newPet models.NewPet + err := ctx.Bind(&newPet) + if err != nil { + return sendPetStoreError(ctx, http.StatusBadRequest, "Invalid format for NewPet") + } + // We now have a pet, let's add it to our "database". + + // We're always asynchronous, so lock unsafe operations below + p.Lock.Lock() + defer p.Lock.Unlock() + + // We handle pets, not NewPets, which have an additional ID field + var pet models.Pet + pet.Name = newPet.Name + pet.Tag = newPet.Tag + pet.Id = p.NextId + p.NextId++ + + // Insert into map + p.Pets[pet.Id] = pet + + // Now, we have to return the NewPet + err = ctx.JSON(http.StatusCreated, pet) + if err != nil { + // Something really bad happened, tell Echo that our handler failed + return err + } + + // Return no error. This refers to the handler. Even if we return an HTTP + // error, but everything else is working properly, tell Echo that we serviced + // the error. We should only return errors from Echo handlers if the actual + // servicing of the error on the infrastructure level failed. Returning an + // HTTP/400 or HTTP/500 from here means Echo/HTTP are still working, so + // return nil. + return nil +} + +func (p *PetStore) FindPetByID(ctx *echo.Context, petId int64) error { + p.Lock.Lock() + defer p.Lock.Unlock() + + pet, found := p.Pets[petId] + if !found { + return sendPetStoreError(ctx, http.StatusNotFound, + fmt.Sprintf("Could not find pet with ID %d", petId)) + } + return ctx.JSON(http.StatusOK, pet) +} + +func (p *PetStore) DeletePet(ctx *echo.Context, id int64) error { + p.Lock.Lock() + defer p.Lock.Unlock() + + _, found := p.Pets[id] + if !found { + return sendPetStoreError(ctx, http.StatusNotFound, + fmt.Sprintf("Could not find pet with ID %d", id)) + } + delete(p.Pets, id) + return ctx.NoContent(http.StatusNoContent) +} diff --git a/examples/petstore-expanded/echo-v5/api/server.cfg.yaml b/examples/petstore-expanded/echo-v5/api/server.cfg.yaml new file mode 100644 index 0000000000..478dc9fc99 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/api/server.cfg.yaml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: api +output: petstore-server.gen.go +additional-imports: + - package: github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api/models + alias: . +generate: + echo5-server: true + embedded-spec: true diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod new file mode 100644 index 0000000000..090320989f --- /dev/null +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -0,0 +1,42 @@ +module github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5 + +go 1.25.0 + +replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ + +require ( + github.com/getkin/kin-openapi v0.133.0 + github.com/labstack/echo/v5 v5.0.4 + github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 + github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/testutil v1.1.0 + github.com/stretchr/testify v1.11.1 +) + +require ( + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/speakeasy-api/jsonpath v0.6.0 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.42.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum new file mode 100644 index 0000000000..6cb9a23cb9 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -0,0 +1,191 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labstack/echo/v5 v5.0.4 h1:ll3I/O8BifjMztj9dD1vx/peZQv8cR2CTUdQK6QxGGc= +github.com/labstack/echo/v5 v5.0.4/go.mod h1:SyvlSdObGjRXeQfCCXW/sybkZdOOQZBmpKF0bvALaeo= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= +github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= +github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= +github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= +github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/petstore-expanded/echo-v5/middleware/middleware.go b/examples/petstore-expanded/echo-v5/middleware/middleware.go new file mode 100644 index 0000000000..0a241fbcf6 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/middleware/middleware.go @@ -0,0 +1,226 @@ +// Package middleware provides OpenAPI request validation middleware for Echo v5. +// +// Adapted from github.com/oapi-codegen/echo-middleware (Echo v4) for use +// with github.com/labstack/echo/v5, which has breaking API changes +// (pointer context, NewHTTPError signature, no HTTPError.Internal field). +// +// This is intentionally inlined in the example because there is no published +// echo-v5 middleware package yet. +// TODO: make an echo-v5 middleware repo +package middleware + +import ( + "context" + "errors" + "fmt" + "log" + "net/http" + "net/url" + "os" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/getkin/kin-openapi/openapi3filter" + "github.com/getkin/kin-openapi/routers" + "github.com/getkin/kin-openapi/routers/gorillamux" + "github.com/labstack/echo/v5" + echomiddleware "github.com/labstack/echo/v5/middleware" +) + +const ( + EchoContextKey = "oapi-codegen/echo-context" + UserDataKey = "oapi-codegen/user-data" +) + +// OapiValidatorFromYamlFile creates validator middleware from a YAML file path. +func OapiValidatorFromYamlFile(path string) (echo.MiddlewareFunc, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("error reading %s: %w", path, err) + } + + spec, err := openapi3.NewLoader().LoadFromData(data) + if err != nil { + return nil, fmt.Errorf("error parsing %s as OpenAPI YAML: %w", path, err) + } + return OapiRequestValidator(spec), nil +} + +// OapiRequestValidator creates middleware to validate incoming requests against +// the given OpenAPI 3.x spec with default configuration. +func OapiRequestValidator(spec *openapi3.T) echo.MiddlewareFunc { + return OapiRequestValidatorWithOptions(spec, nil) +} + +// ErrorHandler is called when there is an error in validation. +type ErrorHandler func(c *echo.Context, err *echo.HTTPError) error + +// MultiErrorHandler is called when the OpenAPI filter returns a MultiError. +type MultiErrorHandler func(openapi3.MultiError) *echo.HTTPError + +// Options to customize request validation. +type Options struct { + ErrorHandler ErrorHandler + Options openapi3filter.Options + ParamDecoder openapi3filter.ContentParameterDecoder + UserData any + Skipper echomiddleware.Skipper + MultiErrorHandler MultiErrorHandler + SilenceServersWarning bool + DoNotValidateServers bool + Prefix string +} + +// OapiRequestValidatorWithOptions creates middleware with explicit configuration. +func OapiRequestValidatorWithOptions(spec *openapi3.T, options *Options) echo.MiddlewareFunc { + if options != nil && options.DoNotValidateServers { + spec.Servers = nil + } + + if spec.Servers != nil && (options == nil || !options.SilenceServersWarning) { + log.Println("WARN: OapiRequestValidatorWithOptions called with an OpenAPI spec that has `Servers` set. This may lead to an HTTP 400 with `no matching operation was found` when sending a valid request, as the validator performs `Host` header validation. If you're expecting `Host` header validation, you can silence this warning by setting `Options.SilenceServersWarning = true`. See https://github.com/oapi-codegen/oapi-codegen/issues/882 for more information.") + } + + router, err := gorillamux.NewRouter(spec) + if err != nil { + panic(err) + } + + skipper := getSkipperFromOptions(options) + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c *echo.Context) error { + if skipper(c) { + return next(c) + } + + err := validateRequestFromContext(c, router, options) + if err != nil { + if options != nil && options.ErrorHandler != nil { + return options.ErrorHandler(c, err) + } + return err + } + return next(c) + } + } +} + +// validateRequestFromContext does the work of validating a request. +func validateRequestFromContext(ctx *echo.Context, router routers.Router, options *Options) *echo.HTTPError { + req := ctx.Request() + + if options != nil && options.Prefix != "" { + clone := req.Clone(req.Context()) + clone.URL.Path = strings.TrimPrefix(clone.URL.Path, options.Prefix) + req = clone + } + + route, pathParams, err := router.FindRoute(req) + if err != nil { + if errors.Is(err, routers.ErrMethodNotAllowed) { + return echo.NewHTTPError(http.StatusMethodNotAllowed, http.StatusText(http.StatusMethodNotAllowed)) + } + + switch e := err.(type) { + case *routers.RouteError: + return echo.NewHTTPError(http.StatusNotFound, e.Reason) + default: + return echo.NewHTTPError(http.StatusInternalServerError, + fmt.Sprintf("error validating route: %s", err.Error())) + } + } + + for k, v := range pathParams { + if unescaped, err := url.PathUnescape(v); err == nil { + pathParams[k] = unescaped + } + } + + validationInput := &openapi3filter.RequestValidationInput{ + Request: req, + PathParams: pathParams, + Route: route, + } + + requestContext := context.WithValue(context.Background(), EchoContextKey, ctx) //nolint:staticcheck + + if options != nil { + validationInput.Options = &options.Options + validationInput.ParamDecoder = options.ParamDecoder + requestContext = context.WithValue(requestContext, UserDataKey, options.UserData) //nolint:staticcheck + } + + err = openapi3filter.ValidateRequest(requestContext, validationInput) + if err != nil { + me := openapi3.MultiError{} + if errors.As(err, &me) { + errFunc := getMultiErrorHandlerFromOptions(options) + return errFunc(me) + } + + switch e := err.(type) { + case *openapi3filter.RequestError: + errorLines := strings.Split(e.Error(), "\n") + return echo.NewHTTPError(http.StatusBadRequest, errorLines[0]) + case *openapi3filter.SecurityRequirementsError: + for _, err := range e.Errors { + httpErr, ok := err.(*echo.HTTPError) + if ok { + return httpErr + } + } + return echo.NewHTTPError(http.StatusForbidden, e.Error()) + default: + return echo.NewHTTPError(http.StatusInternalServerError, + fmt.Sprintf("error validating request: %s", err)) + } + } + return nil +} + +// GetEchoContext gets the echo context from within requests. It returns +// nil if not found or wrong type. +func GetEchoContext(c context.Context) *echo.Context { + iface := c.Value(EchoContextKey) + if iface == nil { + return nil + } + eCtx, ok := iface.(*echo.Context) + if !ok { + return nil + } + return eCtx +} + +// GetUserData gets the user data from the context. +func GetUserData(c context.Context) any { + return c.Value(UserDataKey) +} + +func getSkipperFromOptions(options *Options) echomiddleware.Skipper { + if options == nil { + return echomiddleware.DefaultSkipper + } + + if options.Skipper == nil { + return echomiddleware.DefaultSkipper + } + + return options.Skipper +} + +func getMultiErrorHandlerFromOptions(options *Options) MultiErrorHandler { + if options == nil { + return defaultMultiErrorHandler + } + + if options.MultiErrorHandler == nil { + return defaultMultiErrorHandler + } + + return options.MultiErrorHandler +} + +func defaultMultiErrorHandler(me openapi3.MultiError) *echo.HTTPError { + return echo.NewHTTPError(http.StatusBadRequest, me.Error()) +} diff --git a/examples/petstore-expanded/echo-v5/petstore.go b/examples/petstore-expanded/echo-v5/petstore.go new file mode 100644 index 0000000000..9742cc1939 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/petstore.go @@ -0,0 +1,48 @@ +// This is an example of implementing the Pet Store from the OpenAPI documentation +// found at: +// https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v3.0/petstore.yaml +// +// The code under api/petstore/ has been generated from that specification. +package main + +import ( + "flag" + "fmt" + "log" + "net" + "os" + + "github.com/labstack/echo/v5" + "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api" + mw "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/middleware" +) + +func main() { + port := flag.String("port", "8080", "Port for test HTTP server") + flag.Parse() + + swagger, err := api.GetSwagger() + if err != nil { + fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) + os.Exit(1) + } + + // Clear out the servers array in the swagger spec, that skips validating + // that server names match. We don't know how this thing will be run. + swagger.Servers = nil + + // Create an instance of our handler which satisfies the generated interface + petStore := api.NewPetStore() + + // This is how you set up a basic Echo router + e := echo.New() + // Use our validation middleware to check all requests against the + // OpenAPI schema. + e.Use(mw.OapiRequestValidator(swagger)) + + // We now register our petStore above as the handler for the interface + api.RegisterHandlers(e, petStore) + + // And we serve HTTP until the world ends. + log.Fatal(e.Start(net.JoinHostPort("0.0.0.0", *port))) +} diff --git a/examples/petstore-expanded/echo-v5/petstore_test.go b/examples/petstore-expanded/echo-v5/petstore_test.go new file mode 100644 index 0000000000..61d0530a23 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/petstore_test.go @@ -0,0 +1,152 @@ +// Copyright 2019 DeepMap, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "net/http" + "testing" + + "github.com/labstack/echo/v5" + "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api" + "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/api/models" + mw "github.com/oapi-codegen/oapi-codegen/v2/examples/petstore-expanded/echo-v5/middleware" + "github.com/oapi-codegen/testutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPetStore(t *testing.T) { + var err error + // Here, we Initialize echo + e := echo.New() + + // Now, we create our empty pet store + store := api.NewPetStore() + + // Get the swagger description of our API + swagger, err := api.GetSwagger() + require.NoError(t, err) + + // This disables swagger server name validation. It seems to work poorly, + // and requires our test server to be in that list. + swagger.Servers = nil + + // Validate requests against the OpenAPI spec + e.Use(mw.OapiRequestValidator(swagger)) + + // We register the autogenerated boilerplate and bind our PetStore to this + // echo router. + api.RegisterHandlers(e, store) + + // At this point, we can start sending simulated Http requests, and record + // the HTTP responses to check for validity. This exercises every part of + // the stack except the well-tested HTTP system in Go, which there is no + // point for us to test. + tag := "TagOfSpot" + newPet := models.NewPet{ + Name: "Spot", + Tag: &tag, + } + result := testutil.NewRequest().Post("/pets").WithJsonBody(newPet).GoWithHTTPHandler(t, e) + // We expect 201 code on successful pet insertion + assert.Equal(t, http.StatusCreated, result.Code()) + + // We should have gotten a response from the server with the new pet. Make + // sure that its fields match. + var resultPet models.Pet + err = result.UnmarshalBodyToObject(&resultPet) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, newPet.Name, resultPet.Name) + assert.Equal(t, *newPet.Tag, *resultPet.Tag) + + // This is the Id of the pet we inserted. + petId := resultPet.Id + + // Test the getter function. + result = testutil.NewRequest().Get(fmt.Sprintf("/pets/%d", petId)).WithAcceptJson().GoWithHTTPHandler(t, e) + var resultPet2 models.Pet + err = result.UnmarshalBodyToObject(&resultPet2) + assert.NoError(t, err, "error getting pet") + assert.Equal(t, resultPet, resultPet2) + + // We should get a 404 on invalid ID + result = testutil.NewRequest().Get("/pets/27179095781").WithAcceptJson().GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusNotFound, result.Code()) + var petError models.Error + err = result.UnmarshalBodyToObject(&petError) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, int32(http.StatusNotFound), petError.Code) + + // Let's insert another pet for subsequent tests. + tag = "TagOfFido" + newPet = models.NewPet{ + Name: "Fido", + Tag: &tag, + } + result = testutil.NewRequest().Post("/pets").WithJsonBody(newPet).GoWithHTTPHandler(t, e) + // We expect 201 code on successful pet insertion + assert.Equal(t, http.StatusCreated, result.Code()) + // We should have gotten a response from the server with the new pet. Make + // sure that its fields match. + err = result.UnmarshalBodyToObject(&resultPet) + assert.NoError(t, err, "error unmarshaling response") + petId2 := resultPet.Id + + // Now, list all pets, we should have two + result = testutil.NewRequest().Get("/pets").WithAcceptJson().GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + var petList []models.Pet + err = result.UnmarshalBodyToObject(&petList) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, 2, len(petList)) + + // Filter pets by tag, we should have 1 + petList = nil + result = testutil.NewRequest().Get("/pets?tags=TagOfFido").WithAcceptJson().GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + err = result.UnmarshalBodyToObject(&petList) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, 1, len(petList)) + + // Filter pets by non existent tag, we should have 0 + petList = nil + result = testutil.NewRequest().Get("/pets?tags=NotExists").WithAcceptJson().GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + err = result.UnmarshalBodyToObject(&petList) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, 0, len(petList)) + + // Let's delete non-existent pet + result = testutil.NewRequest().Delete("/pets/7").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusNotFound, result.Code()) + err = result.UnmarshalBodyToObject(&petError) + assert.NoError(t, err, "error unmarshaling PetError") + assert.Equal(t, int32(http.StatusNotFound), petError.Code) + + // Now, delete both real pets + result = testutil.NewRequest().Delete(fmt.Sprintf("/pets/%d", petId)).GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusNoContent, result.Code()) + result = testutil.NewRequest().Delete(fmt.Sprintf("/pets/%d", petId2)).GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusNoContent, result.Code()) + + // Should have no pets left. + petList = nil + result = testutil.NewRequest().Get("/pets").WithAcceptJson().GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + err = result.UnmarshalBodyToObject(&petList) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, 0, len(petList)) +} diff --git a/examples/petstore-expanded/echo-v5/tools/tools.go b/examples/petstore-expanded/echo-v5/tools/tools.go new file mode 100644 index 0000000000..8615cb4c57 --- /dev/null +++ b/examples/petstore-expanded/echo-v5/tools/tools.go @@ -0,0 +1,8 @@ +//go:build tools +// +build tools + +package tools + +import ( + _ "github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen" +) diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 281574a68f..3a77729bff 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -282,6 +282,14 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { } } + var echo5ServerOut string + if opts.Generate.Echo5Server { + echo5ServerOut, err = GenerateEcho5Server(t, ops) + if err != nil { + return "", fmt.Errorf("error generating Go handlers for Paths: %w", err) + } + } + var chiServerOut string if opts.Generate.ChiServer { chiServerOut, err = GenerateChiServer(t, ops) @@ -426,6 +434,13 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { } } + if opts.Generate.Echo5Server { + _, err = w.WriteString(echo5ServerOut) + if err != nil { + return "", fmt.Errorf("error writing server path handlers: %w", err) + } + } + if opts.Generate.ChiServer { _, err = w.WriteString(chiServerOut) if err != nil { @@ -1023,12 +1038,14 @@ func GenerateImports(t *template.Template, externalImports []string, packageName ModuleName string Version string AdditionalImports []AdditionalImport + RouterImports []AdditionalImport }{ ExternalImports: externalImports, PackageName: packageName, ModuleName: modulePath, Version: moduleVersion, AdditionalImports: globalState.options.AdditionalImports, + RouterImports: globalState.options.Generate.RouterImports(), } return GenerateTemplates([]string{"imports.tmpl"}, t, context) diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 6f4df06a0f..0f35d13a90 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -50,6 +50,9 @@ func (o Configuration) Validate() error { if o.Generate.EchoServer { nServers++ } + if o.Generate.Echo5Server { + nServers++ + } if o.Generate.GorillaServer { nServers++ } @@ -112,6 +115,8 @@ type GenerateOptions struct { FiberServer bool `yaml:"fiber-server,omitempty"` // EchoServer specifies whether to generate echo server boilerplate EchoServer bool `yaml:"echo-server,omitempty"` + // Echo5Server specifies whether to generate echo v5 server boilerplate + Echo5Server bool `yaml:"echo5-server,omitempty"` // GinServer specifies whether to generate gin server boilerplate GinServer bool `yaml:"gin-server,omitempty"` // GorillaServer specifies whether to generate Gorilla server boilerplate @@ -130,6 +135,54 @@ type GenerateOptions struct { ServerURLs bool `yaml:"server-urls,omitempty"` } +// RouterImports returns the framework-specific and strict middleware imports +// needed based on which server type is selected. +func (g GenerateOptions) RouterImports() []AdditionalImport { + var imports []AdditionalImport + + switch { + case g.EchoServer: + imports = append(imports, AdditionalImport{Package: "github.com/labstack/echo/v4"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictecho", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo"}) + } + case g.Echo5Server: + imports = append(imports, AdditionalImport{Package: "github.com/labstack/echo/v5"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictecho5", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo/v5"}) + } + case g.ChiServer: + imports = append(imports, AdditionalImport{Package: "github.com/go-chi/chi/v5"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) + } + case g.GinServer: + imports = append(imports, AdditionalImport{Package: "github.com/gin-gonic/gin"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictgin", Package: "github.com/oapi-codegen/runtime/strictmiddleware/gin"}) + } + case g.GorillaServer: + imports = append(imports, AdditionalImport{Package: "github.com/gorilla/mux"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) + } + case g.FiberServer: + imports = append(imports, AdditionalImport{Package: "github.com/gofiber/fiber/v2"}) + case g.IrisServer: + imports = append(imports, AdditionalImport{Package: "github.com/kataras/iris/v12"}) + imports = append(imports, AdditionalImport{Package: "github.com/kataras/iris/v12/core/router"}) + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictiris", Package: "github.com/oapi-codegen/runtime/strictmiddleware/iris"}) + } + case g.StdHTTPServer: + if g.Strict { + imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) + } + } + + return imports +} + func (oo GenerateOptions) Validate() map[string]string { return nil } diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 3c639d22dc..5d9f735506 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -1089,6 +1089,12 @@ func GenerateEchoServer(t *template.Template, operations []OperationDefinition) return GenerateTemplates([]string{"echo/echo-interface.tmpl", "echo/echo-wrappers.tmpl", "echo/echo-register.tmpl"}, t, operations) } +// GenerateEcho5Server generates all the go code for the ServerInterface as well as +// all the wrapper functions around our handlers. +func GenerateEcho5Server(t *template.Template, operations []OperationDefinition) (string, error) { + return GenerateTemplates([]string{"echo/v5/echo-interface.tmpl", "echo/v5/echo-wrappers.tmpl", "echo/v5/echo-register.tmpl"}, t, operations) +} + // GenerateGinServer generates all the go code for the ServerInterface as well as // all the wrapper functions around our handlers. func GenerateGinServer(t *template.Template, operations []OperationDefinition) (string, error) { @@ -1126,6 +1132,9 @@ func GenerateStrictServer(t *template.Template, operations []OperationDefinition if opts.Generate.IrisServer { templates = append(templates, "strict/strict-iris-interface.tmpl", "strict/strict-iris.tmpl") } + if opts.Generate.Echo5Server { + templates = append(templates, "strict/strict-interface.tmpl", "strict/strict-echo5.tmpl") + } return GenerateTemplates(templates, t, operations) } diff --git a/pkg/codegen/templates/echo/v5/echo-interface.tmpl b/pkg/codegen/templates/echo/v5/echo-interface.tmpl new file mode 100644 index 0000000000..1531eef866 --- /dev/null +++ b/pkg/codegen/templates/echo/v5/echo-interface.tmpl @@ -0,0 +1,7 @@ +// ServerInterface represents all server handlers. +type ServerInterface interface { +{{range .}}{{.SummaryAsComment }} +// ({{.Method}} {{.Path}}) +{{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error +{{end}} +} diff --git a/pkg/codegen/templates/echo/v5/echo-register.tmpl b/pkg/codegen/templates/echo/v5/echo-register.tmpl new file mode 100644 index 0000000000..78de21b83e --- /dev/null +++ b/pkg/codegen/templates/echo/v5/echo-register.tmpl @@ -0,0 +1,33 @@ + + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithBaseURL(router, si, "") +} + +// Registers handlers, and prepends BaseURL to the paths, so that the paths +// can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { +{{if .}} + wrapper := ServerInterfaceWrapper{ + Handler: si, + } +{{end}} +{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.OperationId}}) +{{end}} +} diff --git a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl new file mode 100644 index 0000000000..9c1856167c --- /dev/null +++ b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl @@ -0,0 +1,131 @@ +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +{{range .}}{{$opid := .OperationId}}// {{$opid}} converts echo context to params. +func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { + var err error +{{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- + var {{$varName := .GoVariableName}}{{$varName}} {{.TypeDef}} +{{if .IsPassThrough}} + {{$varName}} = ctx.Param("{{.ParamName}}") +{{end}} +{{if .IsJson}} + err = json.Unmarshal([]byte(ctx.Param("{{.ParamName}}")), &{{$varName}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON") + } +{{end}} +{{if .IsStyled}} + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", ctx.Param("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) + } +{{end}} +{{end}} + +{{range .SecurityDefinitions}} + ctx.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}}) +{{end}} + +{{if .RequiresParamObject}} + // Parameter object where we will unmarshal all parameters from the context + var params {{.OperationId}}Params +{{range $paramIdx, $param := .QueryParams}} + {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} + // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- + {{ end }} + {{if .IsStyled}} + err = runtime.BindQueryParameter("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", ctx.QueryParams(), ¶ms.{{.GoName}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) + } + {{else}} + if paramValue := ctx.QueryParam("{{.ParamName}}"); paramValue != "" { + {{if .IsPassThrough}} + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}paramValue + {{end}} + {{if .IsJson}} + var value {{.TypeDef}} + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON") + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value + {{end}} + }{{if .Required}} else { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Query argument {{.ParamName}} is required, but not found")) + }{{end}} + {{end}} +{{end}} + +{{if .HeaderParams}} + headers := ctx.Request().Header +{{range .HeaderParams}}// ------------- {{if .Required}}Required{{else}}Optional{{end}} header parameter "{{.ParamName}}" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("{{.ParamName}}")]; found { + var {{.GoName}} {{.TypeDef}} + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for {{.ParamName}}, got %d", n)) + } +{{if .IsPassThrough}} + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] +{{end}} +{{if .IsJson}} + err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON") + } +{{end}} +{{if .IsStyled}} + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", valueList[0], &{{.GoName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: {{.Explode}}, Required: {{.Required}}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) + } +{{end}} + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} + } {{if .Required}}else { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Header parameter {{.ParamName}} is required, but not found")) + }{{end}} +{{end}} +{{end}} + +{{range .CookieParams}} + if cookie, err := ctx.Cookie("{{.ParamName}}"); err == nil { + {{if .IsPassThrough}} + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}cookie.Value + {{end}} + {{if .IsJson}} + var value {{.TypeDef}} + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unescaping cookie parameter '{{.ParamName}}'") + } + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter '{{.ParamName}}' as JSON") + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value + {{end}} + {{if .IsStyled}} + var value {{.TypeDef}} + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value + {{end}} + }{{if .Required}} else { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Query argument {{.ParamName}} is required, but not found")) + }{{end}} + +{{end}}{{/* .CookieParams */}} + +{{end}}{{/* .RequiresParamObject */}} + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.{{.OperationId}}(ctx{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) + return err +} +{{end}} diff --git a/pkg/codegen/templates/imports.tmpl b/pkg/codegen/templates/imports.tmpl index 4d19422423..8c76dad36d 100644 --- a/pkg/codegen/templates/imports.tmpl +++ b/pkg/codegen/templates/imports.tmpl @@ -28,19 +28,11 @@ import ( "github.com/oapi-codegen/runtime" "github.com/oapi-codegen/nullable" - strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" - strictiris "github.com/oapi-codegen/runtime/strictmiddleware/iris" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" openapi_types "github.com/oapi-codegen/runtime/types" "github.com/getkin/kin-openapi/openapi3" - "github.com/go-chi/chi/v5" - "github.com/labstack/echo/v4" - "github.com/gin-gonic/gin" - "github.com/gofiber/fiber/v2" - "github.com/kataras/iris/v12" - "github.com/kataras/iris/v12/core/router" - "github.com/gorilla/mux" + {{- range .RouterImports}} + {{if .Alias}}{{.Alias}} {{end}}"{{.Package}}" + {{- end}} {{- range .ExternalImports}} {{ . }} {{- end}} diff --git a/pkg/codegen/templates/strict/strict-echo5.tmpl b/pkg/codegen/templates/strict/strict-echo5.tmpl new file mode 100644 index 0000000000..1f377bfdab --- /dev/null +++ b/pkg/codegen/templates/strict/strict-echo5.tmpl @@ -0,0 +1,97 @@ +type StrictHandlerFunc = strictecho5.StrictEchoHandlerFunc +type StrictMiddlewareFunc = strictecho5.StrictEchoMiddlewareFunc + +func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares} +} + +type strictHandler struct { + ssi StrictServerInterface + middlewares []StrictMiddlewareFunc +} + +{{range .}} + {{$opid := .OperationId}} + // {{$opid}} operation middleware + func (sh *strictHandler) {{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error { + var request {{$opid | ucFirst}}RequestObject + + {{range .PathParams -}} + request.{{.GoName}} = {{.GoVariableName}} + {{end -}} + + {{if .RequiresParamObject -}} + request.Params = params + {{end -}} + + {{ if .HasMaskedRequestContentTypes -}} + request.ContentType = ctx.Request().Header.Get("Content-Type") + {{end -}} + + {{$multipleBodies := gt (len .Bodies) 1 -}} + {{range .Bodies -}} + {{if $multipleBodies}}if strings.HasPrefix(ctx.Request().Header.Get("Content-Type"), "{{.ContentType}}") { {{end}} + {{if .IsJSON -}} + var body {{$opid}}{{.NameTag}}RequestBody + if err := ctx.Bind(&body); err != nil { + return err + } + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = &body + {{else if eq .NameTag "Formdata" -}} + if form, err := ctx.FormParams(); err == nil { + var body {{$opid}}{{.NameTag}}RequestBody + if err := runtime.BindForm(&body, form, nil, nil); err != nil { + return err + } + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = &body + } else { + return err + } + {{else if eq .NameTag "Multipart" -}} + {{if eq .ContentType "multipart/form-data" -}} + if reader, err := ctx.Request().MultipartReader(); err != nil { + return err + } else { + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = reader + } + {{else -}} + if _, params, err := mime.ParseMediaType(ctx.Request().Header.Get("Content-Type")); err != nil { + return err + } else if boundary := params["boundary"]; boundary == "" { + return http.ErrMissingBoundary + } else { + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = multipart.NewReader(ctx.Request().Body, boundary) + } + {{end -}} + {{else if eq .NameTag "Text" -}} + data, err := io.ReadAll(ctx.Request().Body) + if err != nil { + return err + } + body := {{$opid}}{{.NameTag}}RequestBody(data) + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = &body + {{else -}} + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = ctx.Request().Body + {{end}}{{/* if eq .NameTag "JSON" */ -}} + {{if $multipleBodies}}}{{end}} + {{end}}{{/* range .Bodies */}} + + handler := func(ctx *echo.Context, request interface{}) (interface{}, error){ + return sh.ssi.{{.OperationId}}(ctx.Request().Context(), request.({{$opid | ucFirst}}RequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "{{.OperationId}}") + } + + response, err := handler(ctx, request) + + if err != nil { + return err + } else if validResponse, ok := response.({{$opid | ucFirst}}ResponseObject); ok { + return validResponse.Visit{{$opid}}Response(ctx.Response()) + } else if response != nil { + return fmt.Errorf("unexpected response type: %T", response) + } + return nil + } +{{end}} From 2b51e3fa64b0d62d53e95bc41d8e891eb99e4479 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 01:24:29 +0000 Subject: [PATCH 06/62] chore(deps): update oapi-codegen/actions action to v0.6.0 (.github/workflows) --- .github/workflows/ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d5e0a1c6c..b1988ded17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,10 +7,9 @@ permissions: contents: read jobs: build: - uses: oapi-codegen/actions/.github/workflows/ci.yml@75566d848d25021f137594c947f26171094fb511 # v0.5.0 + uses: oapi-codegen/actions/.github/workflows/ci.yml@6cf35d4f044f2663dae54547ff6d426e565beb48 # v0.6.0 with: - excluding_versions: '["1.22", "1.23"]' - lint_versions: '["1.25"]' + lint_versions: '["1.26"]' build-binaries: runs-on: ubuntu-latest From 05503dedf9075fb95a0faa98b4ae5ae8dacdb0c2 Mon Sep 17 00:00:00 2001 From: Bilel MEDIMEGH Date: Wed, 4 Mar 2026 23:29:24 +0100 Subject: [PATCH 07/62] AllOf : Only stop when merging schemas with multiple discriminators (#667) * AllOf : Only stop when merging schemas with multiple discriminators * test(codegen): add tests for discriminator propagation in allOf merges Covers all discriminator merge scenarios: - allOf: single discriminator propagated from either schema - allOf: both schemas having discriminators errors - allOf: no discriminators succeeds - non-allOf: any discriminator errors Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Bilel Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.6 --- pkg/codegen/merge_schemas.go | 11 +++++ pkg/codegen/merge_schemas_test.go | 68 +++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 pkg/codegen/merge_schemas_test.go diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index 39c499c7da..a2c979aa19 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -227,6 +227,17 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, e return openapi3.Schema{}, errors.New("merging two schemas with discriminators is not supported") } + // For allOf merges, propagate a discriminator if only one schema has it. + // Merging two different discriminators is not supported. + if s1.Discriminator != nil && s2.Discriminator != nil { + return openapi3.Schema{}, errors.New("merging two schemas with discriminators is not supported") + } + if s1.Discriminator != nil { + result.Discriminator = s1.Discriminator + } else if s2.Discriminator != nil { + result.Discriminator = s2.Discriminator + } + return result, nil } diff --git a/pkg/codegen/merge_schemas_test.go b/pkg/codegen/merge_schemas_test.go new file mode 100644 index 0000000000..9ba9a9f166 --- /dev/null +++ b/pkg/codegen/merge_schemas_test.go @@ -0,0 +1,68 @@ +package codegen + +import ( + "testing" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { + disc := &openapi3.Discriminator{ + PropertyName: "type", + } + + t.Run("allOf with single discriminator on s1 propagates it", func(t *testing.T) { + s1 := openapi3.Schema{Discriminator: disc} + s2 := openapi3.Schema{} + + result, err := mergeOpenapiSchemas(s1, s2, true) + require.NoError(t, err) + assert.Equal(t, disc, result.Discriminator) + }) + + t.Run("allOf with single discriminator on s2 propagates it", func(t *testing.T) { + s1 := openapi3.Schema{} + s2 := openapi3.Schema{Discriminator: disc} + + result, err := mergeOpenapiSchemas(s1, s2, true) + require.NoError(t, err) + assert.Equal(t, disc, result.Discriminator) + }) + + t.Run("allOf with discriminators on both schemas errors", func(t *testing.T) { + disc2 := &openapi3.Discriminator{PropertyName: "kind"} + s1 := openapi3.Schema{Discriminator: disc} + s2 := openapi3.Schema{Discriminator: disc2} + + _, err := mergeOpenapiSchemas(s1, s2, true) + require.Error(t, err) + assert.Contains(t, err.Error(), "discriminators") + }) + + t.Run("allOf with no discriminators succeeds with nil discriminator", func(t *testing.T) { + s1 := openapi3.Schema{} + s2 := openapi3.Schema{} + + result, err := mergeOpenapiSchemas(s1, s2, true) + require.NoError(t, err) + assert.Nil(t, result.Discriminator) + }) + + t.Run("non-allOf with discriminator on s1 errors", func(t *testing.T) { + s1 := openapi3.Schema{Discriminator: disc} + s2 := openapi3.Schema{} + + _, err := mergeOpenapiSchemas(s1, s2, false) + require.Error(t, err) + }) + + t.Run("non-allOf with discriminator on s2 errors", func(t *testing.T) { + s1 := openapi3.Schema{} + s2 := openapi3.Schema{Discriminator: disc} + + _, err := mergeOpenapiSchemas(s1, s2, false) + require.Error(t, err) + }) +} From a13ef41dfc5276e20728bc65b88399d16bee63ad Mon Sep 17 00:00:00 2001 From: nek023 <1830355+nek023@users.noreply.github.com> Date: Thu, 5 Mar 2026 08:51:26 +0900 Subject: [PATCH 08/62] Generate types from components/securitySchemes to be used as a key in context.WithValue (#1187) * Generate types from components/securitySchemes for context.WithValue key * Update generated code * Fix security scheme context key type name mismatch The constants template used `sanitizeGoIdentity | lcFirst` to derive the context key type name, while the type definition in codegen.go used `LowercaseFirstCharacter(SchemaNameToTypeName(...))`. For security scheme names containing underscores (e.g. `api_key`, `petstore_auth`), these produced different results (`api_keyContextKey` vs `apiKeyContextKey`), causing compilation errors. Fix by exposing `SchemaNameToTypeName` as a template function and using it in the constants template so both paths produce the same type name. All affected generated files have been regenerated. Co-Authored-By: Claude Opus 4.6 * Add string() cast for typed security scheme keys in gin, iris, echo-v5 Gin, Iris, and Echo v5 use framework-level string-keyed maps for their Set() methods, which require a string argument. With the new typed context key constants, these calls fail to compile without an explicit string() conversion. Echo v4 already had this cast. Chi, gorilla, stdhttp, and fiber use context.WithValue (which accepts any) and are unaffected. Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Jamie Tanna Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.6 --- .../authenticated-api/echo/api/api.gen.go | 9 ++++-- .../authenticated-api/stdhttp/api/api.gen.go | 5 +++- .../test/any_of/codegen/inline/openapi.gen.go | 7 +++-- .../any_of/codegen/ref_schema/openapi.gen.go | 7 +++-- internal/test/client/client.gen.go | 5 +++- internal/test/client/client.yaml | 4 +++ .../externalref/petstore/externalref.gen.go | 10 +++++-- internal/test/issues/issue-1087/api.gen.go | 3 ++ internal/test/schemas/schemas.gen.go | 25 +++++++++------- pkg/codegen/codegen.go | 29 +++++++++++++++++++ pkg/codegen/template_helpers.go | 1 + pkg/codegen/templates/constants.tmpl | 2 +- pkg/codegen/templates/echo/echo-wrappers.tmpl | 2 +- .../templates/echo/v5/echo-wrappers.tmpl | 2 +- .../templates/fiber/fiber-middleware.tmpl | 2 +- pkg/codegen/templates/gin/gin-wrappers.tmpl | 2 +- .../templates/iris/iris-middleware.tmpl | 2 +- pkg/codegen/utils.go | 12 ++++++++ 18 files changed, 101 insertions(+), 28 deletions(-) diff --git a/examples/authenticated-api/echo/api/api.gen.go b/examples/authenticated-api/echo/api/api.gen.go index 383ab5dc25..1dc357519f 100644 --- a/examples/authenticated-api/echo/api/api.gen.go +++ b/examples/authenticated-api/echo/api/api.gen.go @@ -21,7 +21,7 @@ import ( ) const ( - BearerAuthScopes = "BearerAuth.Scopes" + BearerAuthScopes bearerAuthContextKey = "BearerAuth.Scopes" ) // Error defines model for Error. @@ -44,6 +44,9 @@ type ThingWithID struct { Name string `json:"name"` } +// bearerAuthContextKey is the context key for BearerAuth security scheme +type bearerAuthContextKey string + // AddThingJSONRequestBody defines body for AddThing for application/json ContentType. type AddThingJSONRequestBody = Thing @@ -425,7 +428,7 @@ type ServerInterfaceWrapper struct { func (w *ServerInterfaceWrapper) ListThings(ctx echo.Context) error { var err error - ctx.Set(BearerAuthScopes, []string{}) + ctx.Set(string(BearerAuthScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.ListThings(ctx) @@ -436,7 +439,7 @@ func (w *ServerInterfaceWrapper) ListThings(ctx echo.Context) error { func (w *ServerInterfaceWrapper) AddThing(ctx echo.Context) error { var err error - ctx.Set(BearerAuthScopes, []string{"things:w"}) + ctx.Set(string(BearerAuthScopes), []string{"things:w"}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.AddThing(ctx) diff --git a/examples/authenticated-api/stdhttp/api/api.gen.go b/examples/authenticated-api/stdhttp/api/api.gen.go index 91ced48c3d..bf3af4b293 100644 --- a/examples/authenticated-api/stdhttp/api/api.gen.go +++ b/examples/authenticated-api/stdhttp/api/api.gen.go @@ -22,7 +22,7 @@ import ( ) const ( - BearerAuthScopes = "BearerAuth.Scopes" + BearerAuthScopes bearerAuthContextKey = "BearerAuth.Scopes" ) // Error defines model for Error. @@ -45,6 +45,9 @@ type ThingWithID struct { Name string `json:"name"` } +// bearerAuthContextKey is the context key for BearerAuth security scheme +type bearerAuthContextKey string + // AddThingJSONRequestBody defines body for AddThing for application/json ContentType. type AddThingJSONRequestBody = Thing diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index d3f34bec6e..4179ed9495 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -16,7 +16,7 @@ import ( ) const ( - ApiKeyAuthScopes = "ApiKeyAuth.Scopes" + ApiKeyAuthScopes apiKeyAuthContextKey = "ApiKeyAuth.Scopes" ) // Cat This is a cat @@ -45,6 +45,9 @@ type Rat struct { Squeaks *bool `json:"squeaks,omitempty"` } +// apiKeyAuthContextKey is the context key for ApiKeyAuth security scheme +type apiKeyAuthContextKey string + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -288,7 +291,7 @@ type ServerInterfaceWrapper struct { func (w *ServerInterfaceWrapper) GetPets(ctx echo.Context) error { var err error - ctx.Set(ApiKeyAuthScopes, []string{}) + ctx.Set(string(ApiKeyAuthScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.GetPets(ctx) diff --git a/internal/test/any_of/codegen/ref_schema/openapi.gen.go b/internal/test/any_of/codegen/ref_schema/openapi.gen.go index 38f87c47be..d255052757 100644 --- a/internal/test/any_of/codegen/ref_schema/openapi.gen.go +++ b/internal/test/any_of/codegen/ref_schema/openapi.gen.go @@ -17,7 +17,7 @@ import ( ) const ( - ApiKeyAuthScopes = "ApiKeyAuth.Scopes" + ApiKeyAuthScopes apiKeyAuthContextKey = "ApiKeyAuth.Scopes" ) // Cat This is a cat @@ -56,6 +56,9 @@ type Rat struct { Squeaks *bool `json:"squeaks,omitempty"` } +// apiKeyAuthContextKey is the context key for ApiKeyAuth security scheme +type apiKeyAuthContextKey string + // AsCat returns the union data inside the GetPetsDto_Data as a Cat func (t GetPetsDto_Data) AsCat() (Cat, error) { var body Cat @@ -380,7 +383,7 @@ type ServerInterfaceWrapper struct { func (w *ServerInterfaceWrapper) GetPets(ctx echo.Context) error { var err error - ctx.Set(ApiKeyAuthScopes, []string{}) + ctx.Set(string(ApiKeyAuthScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.GetPets(ctx) diff --git a/internal/test/client/client.gen.go b/internal/test/client/client.gen.go index 275c72cf0f..17135a2ea7 100644 --- a/internal/test/client/client.gen.go +++ b/internal/test/client/client.gen.go @@ -15,7 +15,7 @@ import ( ) const ( - OpenIdScopes = "OpenId.Scopes" + OpenIdScopes openIdContextKey = "OpenId.Scopes" ) // SchemaObject defines model for SchemaObject. @@ -24,6 +24,9 @@ type SchemaObject struct { Role string `json:"role"` } +// openIdContextKey is the context key for OpenId security scheme +type openIdContextKey string + // PostVendorJsonApplicationVndAPIPlusJSONBody defines parameters for PostVendorJson. type PostVendorJsonApplicationVndAPIPlusJSONBody = map[string]interface{} diff --git a/internal/test/client/client.yaml b/internal/test/client/client.yaml index ea4c1c3b1e..15119e593e 100644 --- a/internal/test/client/client.yaml +++ b/internal/test/client/client.yaml @@ -90,6 +90,10 @@ paths: schema: type: object components: + securitySchemes: + OpenId: + type: openIdConnect + openIdConnectUrl: https://example.com/.well-known/openid-configuration schemas: SchemaObject: properties: diff --git a/internal/test/externalref/petstore/externalref.gen.go b/internal/test/externalref/petstore/externalref.gen.go index e8102f0d28..e4b540a404 100644 --- a/internal/test/externalref/petstore/externalref.gen.go +++ b/internal/test/externalref/petstore/externalref.gen.go @@ -18,8 +18,8 @@ import ( ) const ( - Api_keyScopes = "api_key.Scopes" - Petstore_authScopes = "petstore_auth.Scopes" + Api_keyScopes apiKeyContextKey = "api_key.Scopes" + Petstore_authScopes petstoreAuthContextKey = "petstore_auth.Scopes" ) // Defines values for OrderStatus. @@ -166,6 +166,12 @@ type User struct { // UserArray defines model for UserArray. type UserArray = []User +// apiKeyContextKey is the context key for api_key security scheme +type apiKeyContextKey string + +// petstoreAuthContextKey is the context key for petstore_auth security scheme +type petstoreAuthContextKey string + // FindPetsByStatusParams defines parameters for FindPetsByStatus. type FindPetsByStatusParams struct { // Status Status values that need to be considered for filter diff --git a/internal/test/issues/issue-1087/api.gen.go b/internal/test/issues/issue-1087/api.gen.go index 3c408cc8f9..7c154d9115 100644 --- a/internal/test/issues/issue-1087/api.gen.go +++ b/internal/test/issues/issue-1087/api.gen.go @@ -33,6 +33,9 @@ type N404 = externalRef0.Error // ThingResponse Object containing list of Things type ThingResponse = ThingList +// bearerAuthWebhookContextKey is the context key for bearerAuthWebhook security scheme +type bearerAuthWebhookContextKey string + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index 9c0871cb34..f8293f4608 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -25,7 +25,7 @@ import ( ) const ( - Access_tokenScopes = "access_token.Scopes" + Access_tokenScopes accessTokenContextKey = "access_token.Scopes" ) // Defines values for EnumInObjInArrayVal. @@ -111,6 +111,9 @@ type InnerRenamedAnonymousObject struct { // StringInPath defines model for StringInPath. type StringInPath = string +// accessTokenContextKey is the context key for access-token security scheme +type accessTokenContextKey string + // Issue9JSONBody defines parameters for Issue9. type Issue9JSONBody = interface{} @@ -1418,7 +1421,7 @@ type ServerInterfaceWrapper struct { func (w *ServerInterfaceWrapper) EnsureEverythingIsReferenced(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.EnsureEverythingIsReferenced(ctx) @@ -1429,7 +1432,7 @@ func (w *ServerInterfaceWrapper) EnsureEverythingIsReferenced(ctx echo.Context) func (w *ServerInterfaceWrapper) Issue1051(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue1051(ctx) @@ -1440,7 +1443,7 @@ func (w *ServerInterfaceWrapper) Issue1051(ctx echo.Context) error { func (w *ServerInterfaceWrapper) Issue127(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue127(ctx) @@ -1451,7 +1454,7 @@ func (w *ServerInterfaceWrapper) Issue127(ctx echo.Context) error { func (w *ServerInterfaceWrapper) Issue185(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue185(ctx) @@ -1469,7 +1472,7 @@ func (w *ServerInterfaceWrapper) Issue209(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter str: %s", err)) } - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue209(ctx, str) @@ -1487,7 +1490,7 @@ func (w *ServerInterfaceWrapper) Issue30(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter fallthrough: %s", err)) } - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue30(ctx, pFallthrough) @@ -1498,7 +1501,7 @@ func (w *ServerInterfaceWrapper) Issue30(ctx echo.Context) error { func (w *ServerInterfaceWrapper) GetIssues375(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.GetIssues375(ctx) @@ -1516,7 +1519,7 @@ func (w *ServerInterfaceWrapper) Issue41(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1param: %s", err)) } - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue41(ctx, n1param) @@ -1527,7 +1530,7 @@ func (w *ServerInterfaceWrapper) Issue41(ctx echo.Context) error { func (w *ServerInterfaceWrapper) Issue9(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Parameter object where we will unmarshal all parameters from the context var params Issue9Params @@ -1547,7 +1550,7 @@ func (w *ServerInterfaceWrapper) Issue9(ctx echo.Context) error { func (w *ServerInterfaceWrapper) Issue975(ctx echo.Context) error { var err error - ctx.Set(Access_tokenScopes, []string{}) + ctx.Set(string(Access_tokenScopes), []string{}) // Invoke the callback with all the unmarshaled arguments err = w.Handler.Issue975(ctx) diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 3a77729bff..6aedce1805 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -561,6 +561,12 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []Op return "", fmt.Errorf("error generating Go types for component request bodies: %w", err) } allTypes = append(allTypes, bodyTypes...) + + securitySchemeTypes, err := GenerateTypesForSecuritySchemes(t, swagger.Components.SecuritySchemes) + if err != nil { + return "", fmt.Errorf("error generating Go types for component security schemes: %w", err) + } + allTypes = append(allTypes, securitySchemeTypes...) } // Go through all operations, and add their types to allTypes, so that we can @@ -847,6 +853,29 @@ func GenerateTypesForRequestBodies(t *template.Template, bodies map[string]*open return types, nil } +// GenerateTypesForSecuritySchemes generates type definitions for any custom types defined in the +// components/securitySchemes section of the Swagger spec. +func GenerateTypesForSecuritySchemes(t *template.Template, schemes map[string]*openapi3.SecuritySchemeRef) ([]TypeDefinition, error) { + var types []TypeDefinition + + for _, schemeName := range SortedSecuritySchemeKeys(schemes) { + // Generate a type to be used as a key in context.WithValue + goTypeName := LowercaseFirstCharacter(SchemaNameToTypeName(schemeName)) + "ContextKey" + goType := Schema{ + GoType: "string", + Description: fmt.Sprintf("is the context key for %s security scheme", schemeName), + } + + types = append(types, TypeDefinition{ + JsonName: schemeName, + TypeName: goTypeName, + Schema: goType, + }) + } + + return types, nil +} + // GenerateTypes passes a bunch of types to the template engine, and buffers // its output into a string. func GenerateTypes(t *template.Template, types []TypeDefinition) (string, error) { diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index e4d932116a..19c533f1e6 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -350,6 +350,7 @@ var TemplateFunctions = template.FuncMap{ "title": titleCaser.String, "stripNewLines": stripNewLines, "sanitizeGoIdentity": SanitizeGoIdentity, + "schemaNameToTypeName": SchemaNameToTypeName, "toGoString": StringToGoString, "toGoComment": StringWithTypeNameToGoComment, diff --git a/pkg/codegen/templates/constants.tmpl b/pkg/codegen/templates/constants.tmpl index 1c8cbd4922..df434e5377 100644 --- a/pkg/codegen/templates/constants.tmpl +++ b/pkg/codegen/templates/constants.tmpl @@ -1,7 +1,7 @@ {{- if gt (len .SecuritySchemeProviderNames) 0 }} const ( {{range $ProviderName := .SecuritySchemeProviderNames}} - {{- $ProviderName | sanitizeGoIdentity | ucFirst}}Scopes = "{{$ProviderName}}.Scopes" + {{- $ProviderName | sanitizeGoIdentity | ucFirst}}Scopes {{$ProviderName | schemaNameToTypeName | lcFirst}}ContextKey = "{{$ProviderName}}.Scopes" {{end}} ) {{end}} diff --git a/pkg/codegen/templates/echo/echo-wrappers.tmpl b/pkg/codegen/templates/echo/echo-wrappers.tmpl index 584a21f26c..a086d75d4e 100644 --- a/pkg/codegen/templates/echo/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/echo-wrappers.tmpl @@ -26,7 +26,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error { {{end}} {{range .SecurityDefinitions}} - ctx.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}}) + ctx.Set(string({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} diff --git a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl index 9c1856167c..9f7d608dda 100644 --- a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl @@ -26,7 +26,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { {{end}} {{range .SecurityDefinitions}} - ctx.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}}) + ctx.Set(string({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index 63bc2cb831..eab735e5e6 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -36,7 +36,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{end}} {{range .SecurityDefinitions}} - c.Context().SetUserValue({{.ProviderName | ucFirst}}Scopes, {{toStringArray .Scopes}}) + c.Context().SetUserValue(({{.ProviderName | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl index 272e2ec609..e18c0d644c 100644 --- a/pkg/codegen/templates/gin/gin-wrappers.tmpl +++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl @@ -40,7 +40,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { {{end}} {{range .SecurityDefinitions}} - c.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}}) + c.Set(string({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} diff --git a/pkg/codegen/templates/iris/iris-middleware.tmpl b/pkg/codegen/templates/iris/iris-middleware.tmpl index 0bc6b1229b..7ee4ce9b2b 100644 --- a/pkg/codegen/templates/iris/iris-middleware.tmpl +++ b/pkg/codegen/templates/iris/iris-middleware.tmpl @@ -35,7 +35,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { {{end}} {{range .SecurityDefinitions}} - ctx.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}}) + ctx.Set(string({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index adfeb7c89f..b6fb91985f 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -405,6 +405,18 @@ func schemaXOrder(v *openapi3.SchemaRef) (int64, bool) { return 0, false } +// SortedParameterKeys returns sorted keys for a SecuritySchemeRef dict +func SortedSecuritySchemeKeys(dict map[string]*openapi3.SecuritySchemeRef) []string { + keys := make([]string, len(dict)) + i := 0 + for key := range dict { + keys[i] = key + i++ + } + sort.Strings(keys) + return keys +} + // StringInArray checks whether the specified string is present in an array // of strings func StringInArray(str string, array []string) bool { From 5b832190e39a030ac999279fbb2d983f2cc73606 Mon Sep 17 00:00:00 2001 From: Sean Cunniffe <72317985+sean-cunniffe@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:54:35 +1100 Subject: [PATCH 09/62] fix: allow response error handler to set status code (#1963) * fix: allow response error handler to set status code change the order the visit response body function sets the status code and content type so if an error occurs during json marshalling the response error handler can set the status code * fix: buffer JSON responses before writing headers JSON responses in strict server Visit*Response functions are now encoded to a bytes.Buffer before setting headers and calling WriteHeader. This ensures that if JSON encoding fails, nothing has been written to the ResponseWriter, allowing ResponseErrorHandlerFunc to set an appropriate status code (e.g. 500 instead of 200). Non-JSON content types (text, formdata, multipart, binary/io.Reader) retain the original headers-first ordering since their write patterns do not benefit from buffering. Adds regression tests for all content type paths and an integration test verifying that ResponseErrorHandlerFunc can set the status code when JSON encoding fails. Co-Authored-By: Claude Sonnet 4.6 * Address Greptile feedback Also buffer formdata responses before writing headers Apply the same marshal-before-headers pattern to Formdata responses: runtime.MarshalForm is called before setting Content-Type or calling WriteHeader, so if marshalling fails the error handler can still set an appropriate status code. Adds a regression test for the formdata encoding error path. Co-Authored-By: Claude Sonnet 4.6 --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Sonnet 4.6 --- .../issues/issue-1093/api/child/child.gen.go | 9 +- .../issue-1093/api/parent/parent.gen.go | 9 +- .../issue-1208-1209/issue-multi-json.gen.go | 36 +- .../test/issues/issue-1212/pkg1/pkg1.gen.go | 1 + .../issue-1378/bionicle/bionicle.gen.go | 18 +- .../issue-1378/fooservice/fooservice.gen.go | 18 +- .../issue-1529/strict-echo/issue1529.gen.go | 27 +- internal/test/issues/issue-1676/ping.gen.go | 1 + internal/test/issues/issue-1963/config.yaml | 6 + internal/test/issues/issue-1963/generate.go | 3 + .../test/issues/issue-1963/issue1963.gen.go | 590 ++++++++++++++++++ .../test/issues/issue-1963/issue1963_test.go | 239 +++++++ internal/test/issues/issue-1963/spec.yaml | 105 ++++ .../test/issues/issue-2113/gen/api/api.gen.go | 28 +- .../test/issues/issue-2190/issue2190.gen.go | 11 +- .../gen/spec_base/issue.gen.go | 19 +- internal/test/strict-server/chi/server.gen.go | 97 ++- .../test/strict-server/echo/server.gen.go | 97 ++- internal/test/strict-server/gin/server.gen.go | 97 ++- .../test/strict-server/gorilla/server.gen.go | 97 ++- .../test/strict-server/stdhttp/server.gen.go | 97 ++- .../templates/strict/strict-interface.tmpl | 72 ++- 22 files changed, 1482 insertions(+), 195 deletions(-) create mode 100644 internal/test/issues/issue-1963/config.yaml create mode 100644 internal/test/issues/issue-1963/generate.go create mode 100644 internal/test/issues/issue-1963/issue1963.gen.go create mode 100644 internal/test/issues/issue-1963/issue1963_test.go create mode 100644 internal/test/issues/issue-1963/spec.yaml diff --git a/internal/test/issues/issue-1093/api/child/child.gen.go b/internal/test/issues/issue-1093/api/child/child.gen.go index 203fad36e8..d6a7ae9bfc 100644 --- a/internal/test/issues/issue-1093/api/child/child.gen.go +++ b/internal/test/issues/issue-1093/api/child/child.gen.go @@ -90,10 +90,15 @@ type GetPetsResponseObject interface { type GetPets200JSONResponse externalRef0.Pet func (response GetPets200JSONResponse) VisitGetPetsResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1093/api/parent/parent.gen.go b/internal/test/issues/issue-1093/api/parent/parent.gen.go index 916772b07d..462818dea7 100644 --- a/internal/test/issues/issue-1093/api/parent/parent.gen.go +++ b/internal/test/issues/issue-1093/api/parent/parent.gen.go @@ -95,10 +95,15 @@ type GetPetsResponseObject interface { type GetPets200JSONResponse Pet func (response GetPets200JSONResponse) VisitGetPetsResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index 780d45e6a7..c93e087717 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -353,19 +353,29 @@ type TestResponseObject interface { type Test200ApplicationBarPlusJSONResponse Bar func (response Test200ApplicationBarPlusJSONResponse) VisitTestResponse(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/bar+json") w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type Test200ApplicationFooPlusJSONResponse Foo func (response Test200ApplicationFooPlusJSONResponse) VisitTestResponse(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/foo+json") w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type Test201ApplicationBarPlusJSONResponse struct { @@ -373,10 +383,15 @@ type Test201ApplicationBarPlusJSONResponse struct { } func (response Test201ApplicationBarPlusJSONResponse) VisitTestResponse(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/bar+json") w.WriteHeader(201) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type Test201ApplicationFooPlusJSONResponse struct { @@ -384,10 +399,15 @@ type Test201ApplicationFooPlusJSONResponse struct { } func (response Test201ApplicationFooPlusJSONResponse) VisitTestResponse(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/foo+json") w.WriteHeader(201) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index c24850b199..d2922a4a85 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -302,6 +302,7 @@ type Test200MultipartResponse externalRef0.TestMultipartResponse func (response Test200MultipartResponse) VisitTestResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index 863c5fd380..c809c52904 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -200,10 +200,15 @@ type GetBionicleNameResponseObject interface { type GetBionicleName200JSONResponse Bionicle func (response GetBionicleName200JSONResponse) VisitGetBionicleNameResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type GetBionicleName400JSONResponse struct { @@ -211,10 +216,15 @@ type GetBionicleName400JSONResponse struct { } func (response GetBionicleName400JSONResponse) VisitGetBionicleNameResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(400) - - return json.NewEncoder(w).Encode(response.union) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index d076409c14..a6416cfdf2 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -193,10 +193,15 @@ type GetBionicleNameResponseObject interface { type GetBionicleName200JSONResponse externalRef0.Bionicle func (response GetBionicleName200JSONResponse) VisitGetBionicleNameResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type GetBionicleName400JSONResponse struct { @@ -204,10 +209,15 @@ type GetBionicleName400JSONResponse struct { } func (response GetBionicleName400JSONResponse) VisitGetBionicleNameResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(400) - - return json.NewEncoder(w).Encode(response.union) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index cd5260fae4..46655a12d3 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -323,28 +323,43 @@ type TestResponseObject interface { type Test200JSONResponse Test func (response Test200JSONResponse) VisitTestResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type Test200ApplicationJSONProfileBarResponse Test func (response Test200ApplicationJSONProfileBarResponse) VisitTestResponse(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; profile=\"Bar\"") w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type Test200ApplicationJSONProfileFooResponse Test func (response Test200ApplicationJSONProfileFooResponse) VisitTestResponse(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; profile=\"Foo\"") w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-1676/ping.gen.go b/internal/test/issues/issue-1676/ping.gen.go index dcfddc3bc6..19a354080a 100644 --- a/internal/test/issues/issue-1676/ping.gen.go +++ b/internal/test/issues/issue-1676/ping.gen.go @@ -177,6 +177,7 @@ type GetPing200TextResponse struct { } func (response GetPing200TextResponse) VisitGetPingResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.Header().Set("MyHeader", fmt.Sprint(response.Headers.MyHeader)) w.WriteHeader(200) diff --git a/internal/test/issues/issue-1963/config.yaml b/internal/test/issues/issue-1963/config.yaml new file mode 100644 index 0000000000..01b8499a74 --- /dev/null +++ b/internal/test/issues/issue-1963/config.yaml @@ -0,0 +1,6 @@ +package: issue1963 +output: issue1963.gen.go +generate: + std-http-server: true + strict-server: true + models: true diff --git a/internal/test/issues/issue-1963/generate.go b/internal/test/issues/issue-1963/generate.go new file mode 100644 index 0000000000..89436b3beb --- /dev/null +++ b/internal/test/issues/issue-1963/generate.go @@ -0,0 +1,3 @@ +package issue1963 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue-1963/issue1963.gen.go b/internal/test/issues/issue-1963/issue1963.gen.go new file mode 100644 index 0000000000..c47fb4aba0 --- /dev/null +++ b/internal/test/issues/issue-1963/issue1963.gen.go @@ -0,0 +1,590 @@ +//go:build go1.22 + +// Package issue1963 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 issue1963 + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "mime/multipart" + "net/http" + + "github.com/oapi-codegen/runtime" + strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" +) + +// Request defines model for Request. +type Request struct { + Value *string `json:"value,omitempty"` +} + +// Response defines model for Response. +type Response struct { + Value *string `json:"value,omitempty"` +} + +// MultipartEndpointMultipartBody defines parameters for MultipartEndpoint. +type MultipartEndpointMultipartBody struct { + Field *string `json:"field,omitempty"` +} + +// TextEndpointTextBody defines parameters for TextEndpoint. +type TextEndpointTextBody = string + +// FormdataEndpointFormdataRequestBody defines body for FormdataEndpoint for application/x-www-form-urlencoded ContentType. +type FormdataEndpointFormdataRequestBody = Request + +// JsonEndpointJSONRequestBody defines body for JsonEndpoint for application/json ContentType. +type JsonEndpointJSONRequestBody = Request + +// MultipartEndpointMultipartRequestBody defines body for MultipartEndpoint for multipart/form-data ContentType. +type MultipartEndpointMultipartRequestBody MultipartEndpointMultipartBody + +// TextEndpointTextRequestBody defines body for TextEndpoint for text/plain ContentType. +type TextEndpointTextRequestBody = TextEndpointTextBody + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (POST /binary) + BinaryEndpoint(w http.ResponseWriter, r *http.Request) + + // (POST /formdata) + FormdataEndpoint(w http.ResponseWriter, r *http.Request) + + // (POST /json) + JsonEndpoint(w http.ResponseWriter, r *http.Request) + + // (POST /multipart) + MultipartEndpoint(w http.ResponseWriter, r *http.Request) + + // (POST /text) + TextEndpoint(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 + +// BinaryEndpoint operation middleware +func (siw *ServerInterfaceWrapper) BinaryEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.BinaryEndpoint(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// FormdataEndpoint operation middleware +func (siw *ServerInterfaceWrapper) FormdataEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.FormdataEndpoint(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// JsonEndpoint operation middleware +func (siw *ServerInterfaceWrapper) JsonEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.JsonEndpoint(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// MultipartEndpoint operation middleware +func (siw *ServerInterfaceWrapper) MultipartEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.MultipartEndpoint(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// TextEndpoint operation middleware +func (siw *ServerInterfaceWrapper) TextEndpoint(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.TextEndpoint(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)) + ServeHTTP(w http.ResponseWriter, r *http.Request) +} + +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("POST "+options.BaseURL+"/binary", wrapper.BinaryEndpoint) + m.HandleFunc("POST "+options.BaseURL+"/formdata", wrapper.FormdataEndpoint) + m.HandleFunc("POST "+options.BaseURL+"/json", wrapper.JsonEndpoint) + m.HandleFunc("POST "+options.BaseURL+"/multipart", wrapper.MultipartEndpoint) + m.HandleFunc("POST "+options.BaseURL+"/text", wrapper.TextEndpoint) + + return m +} + +type BinaryEndpointRequestObject struct { + Body io.Reader +} + +type BinaryEndpointResponseObject interface { + VisitBinaryEndpointResponse(w http.ResponseWriter) error +} + +type BinaryEndpoint200ApplicationoctetStreamResponse struct { + Body io.Reader + ContentLength int64 +} + +func (response BinaryEndpoint200ApplicationoctetStreamResponse) VisitBinaryEndpointResponse(w http.ResponseWriter) error { + + w.Header().Set("Content-Type", "application/octet-stream") + if response.ContentLength != 0 { + w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) + } + w.WriteHeader(200) + + if closer, ok := response.Body.(io.ReadCloser); ok { + defer closer.Close() + } + _, err := io.Copy(w, response.Body) + return err +} + +type FormdataEndpointRequestObject struct { + Body *FormdataEndpointFormdataRequestBody +} + +type FormdataEndpointResponseObject interface { + VisitFormdataEndpointResponse(w http.ResponseWriter) error +} + +type FormdataEndpoint200FormdataResponse Response + +func (response FormdataEndpoint200FormdataResponse) VisitFormdataEndpointResponse(w http.ResponseWriter) error { + + form, err := runtime.MarshalForm(response, nil) + if err != nil { + return err + } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err +} + +type JsonEndpointRequestObject struct { + Body *JsonEndpointJSONRequestBody +} + +type JsonEndpointResponseObject interface { + VisitJsonEndpointResponse(w http.ResponseWriter) error +} + +type JsonEndpoint200JSONResponse Response + +func (response JsonEndpoint200JSONResponse) VisitJsonEndpointResponse(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 MultipartEndpointRequestObject struct { + Body *multipart.Reader +} + +type MultipartEndpointResponseObject interface { + VisitMultipartEndpointResponse(w http.ResponseWriter) error +} + +type MultipartEndpoint200MultipartResponse func(writer *multipart.Writer) error + +func (response MultipartEndpoint200MultipartResponse) VisitMultipartEndpointResponse(w http.ResponseWriter) error { + writer := multipart.NewWriter(w) + + w.Header().Set("Content-Type", writer.FormDataContentType()) + w.WriteHeader(200) + + defer writer.Close() + return response(writer) +} + +type TextEndpointRequestObject struct { + Body *TextEndpointTextRequestBody +} + +type TextEndpointResponseObject interface { + VisitTextEndpointResponse(w http.ResponseWriter) error +} + +type TextEndpoint200TextResponse string + +func (response TextEndpoint200TextResponse) VisitTextEndpointResponse(w http.ResponseWriter) error { + + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(200) + + _, err := w.Write([]byte(response)) + return err +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (POST /binary) + BinaryEndpoint(ctx context.Context, request BinaryEndpointRequestObject) (BinaryEndpointResponseObject, error) + + // (POST /formdata) + FormdataEndpoint(ctx context.Context, request FormdataEndpointRequestObject) (FormdataEndpointResponseObject, error) + + // (POST /json) + JsonEndpoint(ctx context.Context, request JsonEndpointRequestObject) (JsonEndpointResponseObject, error) + + // (POST /multipart) + MultipartEndpoint(ctx context.Context, request MultipartEndpointRequestObject) (MultipartEndpointResponseObject, error) + + // (POST /text) + TextEndpoint(ctx context.Context, request TextEndpointRequestObject) (TextEndpointResponseObject, error) +} + +type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc +type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc + +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 +} + +// BinaryEndpoint operation middleware +func (sh *strictHandler) BinaryEndpoint(w http.ResponseWriter, r *http.Request) { + var request BinaryEndpointRequestObject + + request.Body = r.Body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.BinaryEndpoint(ctx, request.(BinaryEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "BinaryEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(BinaryEndpointResponseObject); ok { + if err := validResponse.VisitBinaryEndpointResponse(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)) + } +} + +// FormdataEndpoint operation middleware +func (sh *strictHandler) FormdataEndpoint(w http.ResponseWriter, r *http.Request) { + var request FormdataEndpointRequestObject + + if err := r.ParseForm(); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode formdata: %w", err)) + return + } + var body FormdataEndpointFormdataRequestBody + if err := runtime.BindForm(&body, r.Form, nil, nil); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't bind formdata: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.FormdataEndpoint(ctx, request.(FormdataEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "FormdataEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(FormdataEndpointResponseObject); ok { + if err := validResponse.VisitFormdataEndpointResponse(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)) + } +} + +// JsonEndpoint operation middleware +func (sh *strictHandler) JsonEndpoint(w http.ResponseWriter, r *http.Request) { + var request JsonEndpointRequestObject + + var body JsonEndpointJSONRequestBody + 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.JsonEndpoint(ctx, request.(JsonEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "JsonEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(JsonEndpointResponseObject); ok { + if err := validResponse.VisitJsonEndpointResponse(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)) + } +} + +// MultipartEndpoint operation middleware +func (sh *strictHandler) MultipartEndpoint(w http.ResponseWriter, r *http.Request) { + var request MultipartEndpointRequestObject + + if reader, err := r.MultipartReader(); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode multipart body: %w", err)) + return + } else { + request.Body = reader + } + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.MultipartEndpoint(ctx, request.(MultipartEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "MultipartEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(MultipartEndpointResponseObject); ok { + if err := validResponse.VisitMultipartEndpointResponse(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)) + } +} + +// TextEndpoint operation middleware +func (sh *strictHandler) TextEndpoint(w http.ResponseWriter, r *http.Request) { + var request TextEndpointRequestObject + + data, err := io.ReadAll(r.Body) + if err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't read body: %w", err)) + return + } + body := TextEndpointTextRequestBody(data) + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.TextEndpoint(ctx, request.(TextEndpointRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "TextEndpoint") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(TextEndpointResponseObject); ok { + if err := validResponse.VisitTextEndpointResponse(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/issues/issue-1963/issue1963_test.go b/internal/test/issues/issue-1963/issue1963_test.go new file mode 100644 index 0000000000..159e7ab920 --- /dev/null +++ b/internal/test/issues/issue-1963/issue1963_test.go @@ -0,0 +1,239 @@ +package issue1963 + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "mime" + "mime/multipart" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/oapi-codegen/runtime" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// These tests are regression tests for https://github.com/oapi-codegen/oapi-codegen/issues/1963. +// +// The issue: in generated strict server Visit*Response functions, WriteHeader +// was called before marshalling the response body. If JSON encoding failed, +// ResponseErrorHandlerFunc could not set a different status code because 200 +// was already written. +// +// The fix: JSON responses are buffered via bytes.Buffer before headers are sent. +// Non-JSON responses retain the original headers-first ordering. + +// TestJsonEndpoint_Success verifies JSON responses buffer the body and set +// Content-Type and status code correctly. +func TestJsonEndpoint_Success(t *testing.T) { + value := "hello" + resp := JsonEndpoint200JSONResponse{Value: &value} + w := httptest.NewRecorder() + + err := resp.VisitJsonEndpointResponse(w) + require.NoError(t, err) + assert.Equal(t, 200, w.Code) + assert.True(t, strings.HasPrefix(w.Header().Get("Content-Type"), "application/json")) + + var body Response + require.NoError(t, json.NewDecoder(w.Body).Decode(&body)) + assert.Equal(t, &value, body.Value) +} + +// TestTextEndpoint_Success verifies text responses set Content-Type and status code. +func TestTextEndpoint_Success(t *testing.T) { + resp := TextEndpoint200TextResponse("hello world") + w := httptest.NewRecorder() + + err := resp.VisitTextEndpointResponse(w) + require.NoError(t, err) + assert.Equal(t, 200, w.Code) + assert.Equal(t, "text/plain", w.Header().Get("Content-Type")) + assert.Equal(t, "hello world", w.Body.String()) +} + +// TestFormdataEndpoint_Success verifies formdata responses set Content-Type and status code. +func TestFormdataEndpoint_Success(t *testing.T) { + value := "test" + resp := FormdataEndpoint200FormdataResponse{Value: &value} + w := httptest.NewRecorder() + + err := resp.VisitFormdataEndpointResponse(w) + require.NoError(t, err) + assert.Equal(t, 200, w.Code) + assert.Equal(t, "application/x-www-form-urlencoded", w.Header().Get("Content-Type")) + assert.Contains(t, w.Body.String(), "value=test") +} + +// TestMultipartEndpoint_Success verifies multipart responses set Content-Type and status code. +func TestMultipartEndpoint_Success(t *testing.T) { + resp := MultipartEndpoint200MultipartResponse(func(writer *multipart.Writer) error { + return writer.WriteField("field", "value") + }) + w := httptest.NewRecorder() + + err := resp.VisitMultipartEndpointResponse(w) + require.NoError(t, err) + assert.Equal(t, 200, w.Code) + ct, params, err := mime.ParseMediaType(w.Header().Get("Content-Type")) + require.NoError(t, err) + assert.Equal(t, "multipart/form-data", ct) + + reader := multipart.NewReader(w.Body, params["boundary"]) + part, err := reader.NextPart() + require.NoError(t, err) + assert.Equal(t, "field", part.FormName()) + data, err := io.ReadAll(part) + require.NoError(t, err) + assert.Equal(t, "value", string(data)) +} + +// TestBinaryEndpoint_Success verifies binary (io.Reader) responses set Content-Type and status code. +func TestBinaryEndpoint_Success(t *testing.T) { + body := strings.NewReader("binary data") + resp := BinaryEndpoint200ApplicationoctetStreamResponse{ + Body: body, + ContentLength: int64(len("binary data")), + } + w := httptest.NewRecorder() + + err := resp.VisitBinaryEndpointResponse(w) + require.NoError(t, err) + assert.Equal(t, 200, w.Code) + assert.Equal(t, "application/octet-stream", w.Header().Get("Content-Type")) + assert.Equal(t, "11", w.Header().Get("Content-Length")) + assert.Equal(t, "binary data", w.Body.String()) +} + +// TestJsonEndpoint_EncodingError_ErrorHandlerCanSetStatus is the core +// regression test. It verifies that when JSON encoding fails, the +// ResponseErrorHandlerFunc can still set the HTTP status code because nothing +// has been written to the ResponseWriter yet. +// +// We use a custom StrictServerInterface implementation that returns a response +// object whose Visit method will fail during JSON encoding. +func TestJsonEndpoint_EncodingError_ErrorHandlerCanSetStatus(t *testing.T) { + server := &errorServer{} + var errHandlerCalled bool + handler := NewStrictHandlerWithOptions(server, nil, 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) { + errHandlerCalled = true + w.WriteHeader(http.StatusInternalServerError) + }, + }) + mux := http.NewServeMux() + HandlerFromMux(handler, mux) + + body := `{"value": "test"}` + req := httptest.NewRequest(http.MethodPost, "/json", strings.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + w := httptest.NewRecorder() + + mux.ServeHTTP(w, req) + + assert.True(t, errHandlerCalled, "ResponseErrorHandlerFunc should have been called") + assert.Equal(t, http.StatusInternalServerError, w.Code, + "error handler should be able to set status code to 500 when JSON encoding fails") + assert.Empty(t, w.Header().Get("Content-Type"), + "Content-Type should not be set when encoding fails before headers are written") +} + +// errorServer implements StrictServerInterface and returns a response whose +// JSON encoding will fail. +type errorServer struct{} + +func (s *errorServer) JsonEndpoint(_ context.Context, _ JsonEndpointRequestObject) (JsonEndpointResponseObject, error) { + return &unmarshalableJSONResponse{}, nil +} + +func (s *errorServer) TextEndpoint(_ context.Context, _ TextEndpointRequestObject) (TextEndpointResponseObject, error) { + return nil, fmt.Errorf("not implemented") +} + +func (s *errorServer) FormdataEndpoint(_ context.Context, _ FormdataEndpointRequestObject) (FormdataEndpointResponseObject, error) { + return &unmarshalableFormdataResponse{}, nil +} + +func (s *errorServer) MultipartEndpoint(_ context.Context, _ MultipartEndpointRequestObject) (MultipartEndpointResponseObject, error) { + return nil, fmt.Errorf("not implemented") +} + +func (s *errorServer) BinaryEndpoint(_ context.Context, _ BinaryEndpointRequestObject) (BinaryEndpointResponseObject, error) { + return nil, fmt.Errorf("not implemented") +} + +// TestFormdataEndpoint_MarshalError verifies that when form marshalling fails, +// ResponseErrorHandlerFunc can set the status code because nothing has been +// written to the ResponseWriter yet. +func TestFormdataEndpoint_MarshalError_ErrorHandlerCanSetStatus(t *testing.T) { + server := &errorServer{} + var errHandlerCalled bool + handler := NewStrictHandlerWithOptions(server, nil, 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) { + errHandlerCalled = true + w.WriteHeader(http.StatusInternalServerError) + }, + }) + mux := http.NewServeMux() + HandlerFromMux(handler, mux) + + body := "value=test" + req := httptest.NewRequest(http.MethodPost, "/formdata", strings.NewReader(body)) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + w := httptest.NewRecorder() + + mux.ServeHTTP(w, req) + + assert.True(t, errHandlerCalled, "ResponseErrorHandlerFunc should have been called") + assert.Equal(t, http.StatusInternalServerError, w.Code, + "error handler should be able to set status code to 500 when form marshalling fails") + assert.Empty(t, w.Header().Get("Content-Type"), + "Content-Type should not be set when marshalling fails before headers are written") +} + +// unmarshalableJSONResponse implements JsonEndpointResponseObject with a Visit +// method that follows the exact same pattern as the generated code but +// encodes a value that json.Encoder cannot marshal (a channel). +type unmarshalableJSONResponse struct{} + +func (u *unmarshalableJSONResponse) VisitJsonEndpointResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + // Channels cannot be JSON-encoded; this will return an error. + if err := json.NewEncoder(&buf).Encode(map[string]any{ + "bad": make(chan int), + }); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +// unmarshalableFormdataResponse implements FormdataEndpointResponseObject with +// a Visit method that follows the generated code pattern but passes a channel +// to runtime.MarshalForm, which will always fail (it expects a struct or map). +type unmarshalableFormdataResponse struct{} + +func (u *unmarshalableFormdataResponse) VisitFormdataEndpointResponse(w http.ResponseWriter) error { + // A channel is never a valid form body; MarshalForm will return an error. + form, err := runtime.MarshalForm(make(chan int), nil) + if err != nil { + return err + } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err +} diff --git a/internal/test/issues/issue-1963/spec.yaml b/internal/test/issues/issue-1963/spec.yaml new file mode 100644 index 0000000000..a96d16a5af --- /dev/null +++ b/internal/test/issues/issue-1963/spec.yaml @@ -0,0 +1,105 @@ +openapi: 3.0.3 +info: + title: issue-1963 + version: 1.0.0 +paths: + /json: + post: + operationId: JsonEndpoint + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Request" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + /text: + post: + operationId: TextEndpoint + requestBody: + required: true + content: + text/plain: + schema: + type: string + responses: + "200": + description: OK + content: + text/plain: + schema: + type: string + /formdata: + post: + operationId: FormdataEndpoint + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/Request" + responses: + "200": + description: OK + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/Response" + /multipart: + post: + operationId: MultipartEndpoint + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + field: + type: string + responses: + "200": + description: OK + content: + multipart/form-data: + schema: + type: object + properties: + field: + type: string + /binary: + post: + operationId: BinaryEndpoint + requestBody: + required: true + content: + application/octet-stream: + schema: + type: string + format: binary + responses: + "200": + description: OK + content: + application/octet-stream: + schema: + type: string + format: binary +components: + schemas: + Request: + type: object + properties: + value: + type: string + Response: + type: object + properties: + value: + type: string diff --git a/internal/test/issues/issue-2113/gen/api/api.gen.go b/internal/test/issues/issue-2113/gen/api/api.gen.go index 6562a7f30d..626e5ea1f6 100644 --- a/internal/test/issues/issue-2113/gen/api/api.gen.go +++ b/internal/test/issues/issue-2113/gen/api/api.gen.go @@ -4,6 +4,7 @@ package api import ( + "bytes" "context" "encoding/json" "fmt" @@ -183,19 +184,29 @@ type ListThingsResponseObject interface { type ListThings200JSONResponse []string func (response ListThings200JSONResponse) VisitListThingsResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type ListThings400JSONResponse struct{ externalRef0.StandardError } func (response ListThings400JSONResponse) VisitListThingsResponse(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(400) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type ListThingsdefaultJSONResponse struct { @@ -204,10 +215,15 @@ type ListThingsdefaultJSONResponse struct { } func (response ListThingsdefaultJSONResponse) VisitListThingsResponse(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") w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/issues/issue-2190/issue2190.gen.go b/internal/test/issues/issue-2190/issue2190.gen.go index c22e32724c..409eba372f 100644 --- a/internal/test/issues/issue-2190/issue2190.gen.go +++ b/internal/test/issues/issue-2190/issue2190.gen.go @@ -6,6 +6,7 @@ package issue2190 import ( + "bytes" "context" "encoding/json" "fmt" @@ -409,15 +410,21 @@ type GetTestResponseObject interface { type GetTest200JSONResponse struct{ SuccessJSONResponse } func (response GetTest200JSONResponse) VisitGetTestResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type GetTest401TextResponse UnauthorizedTextResponse func (response GetTest401TextResponse) VisitGetTestResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(401) diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go index 1a1c761002..f96b78c9b2 100644 --- a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go @@ -4,6 +4,7 @@ package spec_base import ( + "bytes" "context" "encoding/json" "fmt" @@ -218,10 +219,15 @@ type PostInvalidExtRefTroubleResponseObject interface { type PostInvalidExtRefTrouble300JSONResponse struct{ externalRef0.Pascal } func (response PostInvalidExtRefTrouble300JSONResponse) VisitPostInvalidExtRefTroubleResponse(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(300) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type PostNoTroubleRequestObject struct { @@ -239,10 +245,15 @@ type PostNoTrouble200JSONResponse struct { } func (response PostNoTrouble200JSONResponse) VisitPostNoTroubleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index a7c569b2c5..01ef76a0c7 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -593,10 +593,15 @@ type JSONExampleResponseObject interface { type JSONExample200JSONResponse Example func (response JSONExample200JSONResponse) VisitJSONExampleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type JSONExample400Response = BadrequestResponse @@ -627,6 +632,7 @@ type MultipartExample200MultipartResponse func(writer *multipart.Writer) error func (response MultipartExample200MultipartResponse) VisitMultipartExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -662,6 +668,7 @@ type MultipartRelatedExample200MultipartResponse func(writer *multipart.Writer) func (response MultipartRelatedExample200MultipartResponse) VisitMultipartRelatedExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) @@ -700,24 +707,29 @@ type MultipleRequestAndResponseTypesResponseObject interface { type MultipleRequestAndResponseTypes200JSONResponse Example func (response MultipleRequestAndResponseTypes200JSONResponse) VisitMultipleRequestAndResponseTypesResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type MultipleRequestAndResponseTypes200FormdataResponse Example func (response MultipleRequestAndResponseTypes200FormdataResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type MultipleRequestAndResponseTypes200ImagepngResponse struct { @@ -726,6 +738,7 @@ type MultipleRequestAndResponseTypes200ImagepngResponse struct { } func (response MultipleRequestAndResponseTypes200ImagepngResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "image/png") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -743,6 +756,7 @@ type MultipleRequestAndResponseTypes200MultipartResponse func(writer *multipart. func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -753,6 +767,7 @@ func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipl type MultipleRequestAndResponseTypes200TextResponse string func (response MultipleRequestAndResponseTypes200TextResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -778,10 +793,15 @@ type RequiredJSONBodyResponseObject interface { type RequiredJSONBody200JSONResponse Example func (response RequiredJSONBody200JSONResponse) VisitRequiredJSONBodyResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type RequiredJSONBody400Response = BadrequestResponse @@ -811,6 +831,7 @@ type RequiredTextBodyResponseObject interface { type RequiredTextBody200TextResponse string func (response RequiredTextBody200TextResponse) VisitRequiredTextBodyResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -845,6 +866,7 @@ type ReservedGoKeywordParametersResponseObject interface { type ReservedGoKeywordParameters200TextResponse string func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -863,12 +885,17 @@ type ReusableResponsesResponseObject interface { type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type ReusableResponses400Response = BadrequestResponse @@ -898,6 +925,7 @@ type TextExampleResponseObject interface { type TextExample200TextResponse string func (response TextExample200TextResponse) VisitTextExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -935,6 +963,7 @@ type UnknownExample200Videomp4Response struct { } func (response UnknownExample200Videomp4Response) VisitUnknownExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "video/mp4") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -980,6 +1009,7 @@ type UnspecifiedContentType200VideoResponse struct { } func (response UnspecifiedContentType200VideoResponse) VisitUnspecifiedContentTypeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", response.ContentType) if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -1036,15 +1066,15 @@ type URLEncodedExampleResponseObject interface { type URLEncodedExample200FormdataResponse Example func (response URLEncodedExample200FormdataResponse) VisitURLEncodedExampleResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type URLEncodedExample400Response = BadrequestResponse @@ -1083,12 +1113,17 @@ type HeadersExample200JSONResponse struct { } func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type HeadersExample400Response = BadrequestResponse @@ -1126,12 +1161,17 @@ type UnionExample200ApplicationAlternativePlusJSONResponse struct { } func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnionExampleResponse(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/alternative+json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type UnionExample200JSONResponse struct { @@ -1142,12 +1182,17 @@ type UnionExample200JSONResponse struct { } func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body.union) + _, err := buf.WriteTo(w) + return err } type UnionExample400Response = BadrequestResponse diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index e8e335c74a..9770f43472 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -315,10 +315,15 @@ type JSONExampleResponseObject interface { type JSONExample200JSONResponse Example func (response JSONExample200JSONResponse) VisitJSONExampleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type JSONExample400Response = BadrequestResponse @@ -349,6 +354,7 @@ type MultipartExample200MultipartResponse func(writer *multipart.Writer) error func (response MultipartExample200MultipartResponse) VisitMultipartExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -384,6 +390,7 @@ type MultipartRelatedExample200MultipartResponse func(writer *multipart.Writer) func (response MultipartRelatedExample200MultipartResponse) VisitMultipartRelatedExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) @@ -422,24 +429,29 @@ type MultipleRequestAndResponseTypesResponseObject interface { type MultipleRequestAndResponseTypes200JSONResponse Example func (response MultipleRequestAndResponseTypes200JSONResponse) VisitMultipleRequestAndResponseTypesResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type MultipleRequestAndResponseTypes200FormdataResponse Example func (response MultipleRequestAndResponseTypes200FormdataResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type MultipleRequestAndResponseTypes200ImagepngResponse struct { @@ -448,6 +460,7 @@ type MultipleRequestAndResponseTypes200ImagepngResponse struct { } func (response MultipleRequestAndResponseTypes200ImagepngResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "image/png") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -465,6 +478,7 @@ type MultipleRequestAndResponseTypes200MultipartResponse func(writer *multipart. func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -475,6 +489,7 @@ func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipl type MultipleRequestAndResponseTypes200TextResponse string func (response MultipleRequestAndResponseTypes200TextResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -500,10 +515,15 @@ type RequiredJSONBodyResponseObject interface { type RequiredJSONBody200JSONResponse Example func (response RequiredJSONBody200JSONResponse) VisitRequiredJSONBodyResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type RequiredJSONBody400Response = BadrequestResponse @@ -533,6 +553,7 @@ type RequiredTextBodyResponseObject interface { type RequiredTextBody200TextResponse string func (response RequiredTextBody200TextResponse) VisitRequiredTextBodyResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -567,6 +588,7 @@ type ReservedGoKeywordParametersResponseObject interface { type ReservedGoKeywordParameters200TextResponse string func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -585,12 +607,17 @@ type ReusableResponsesResponseObject interface { type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type ReusableResponses400Response = BadrequestResponse @@ -620,6 +647,7 @@ type TextExampleResponseObject interface { type TextExample200TextResponse string func (response TextExample200TextResponse) VisitTextExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -657,6 +685,7 @@ type UnknownExample200Videomp4Response struct { } func (response UnknownExample200Videomp4Response) VisitUnknownExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "video/mp4") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -702,6 +731,7 @@ type UnspecifiedContentType200VideoResponse struct { } func (response UnspecifiedContentType200VideoResponse) VisitUnspecifiedContentTypeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", response.ContentType) if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -758,15 +788,15 @@ type URLEncodedExampleResponseObject interface { type URLEncodedExample200FormdataResponse Example func (response URLEncodedExample200FormdataResponse) VisitURLEncodedExampleResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type URLEncodedExample400Response = BadrequestResponse @@ -805,12 +835,17 @@ type HeadersExample200JSONResponse struct { } func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type HeadersExample400Response = BadrequestResponse @@ -848,12 +883,17 @@ type UnionExample200ApplicationAlternativePlusJSONResponse struct { } func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnionExampleResponse(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/alternative+json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type UnionExample200JSONResponse struct { @@ -864,12 +904,17 @@ type UnionExample200JSONResponse struct { } func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body.union) + _, err := buf.WriteTo(w) + return err } type UnionExample400Response = BadrequestResponse diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index b664de93d3..25b3f654db 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -388,10 +388,15 @@ type JSONExampleResponseObject interface { type JSONExample200JSONResponse Example func (response JSONExample200JSONResponse) VisitJSONExampleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type JSONExample400Response = BadrequestResponse @@ -422,6 +427,7 @@ type MultipartExample200MultipartResponse func(writer *multipart.Writer) error func (response MultipartExample200MultipartResponse) VisitMultipartExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -457,6 +463,7 @@ type MultipartRelatedExample200MultipartResponse func(writer *multipart.Writer) func (response MultipartRelatedExample200MultipartResponse) VisitMultipartRelatedExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) @@ -495,24 +502,29 @@ type MultipleRequestAndResponseTypesResponseObject interface { type MultipleRequestAndResponseTypes200JSONResponse Example func (response MultipleRequestAndResponseTypes200JSONResponse) VisitMultipleRequestAndResponseTypesResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type MultipleRequestAndResponseTypes200FormdataResponse Example func (response MultipleRequestAndResponseTypes200FormdataResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type MultipleRequestAndResponseTypes200ImagepngResponse struct { @@ -521,6 +533,7 @@ type MultipleRequestAndResponseTypes200ImagepngResponse struct { } func (response MultipleRequestAndResponseTypes200ImagepngResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "image/png") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -538,6 +551,7 @@ type MultipleRequestAndResponseTypes200MultipartResponse func(writer *multipart. func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -548,6 +562,7 @@ func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipl type MultipleRequestAndResponseTypes200TextResponse string func (response MultipleRequestAndResponseTypes200TextResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -573,10 +588,15 @@ type RequiredJSONBodyResponseObject interface { type RequiredJSONBody200JSONResponse Example func (response RequiredJSONBody200JSONResponse) VisitRequiredJSONBodyResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type RequiredJSONBody400Response = BadrequestResponse @@ -606,6 +626,7 @@ type RequiredTextBodyResponseObject interface { type RequiredTextBody200TextResponse string func (response RequiredTextBody200TextResponse) VisitRequiredTextBodyResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -640,6 +661,7 @@ type ReservedGoKeywordParametersResponseObject interface { type ReservedGoKeywordParameters200TextResponse string func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -658,12 +680,17 @@ type ReusableResponsesResponseObject interface { type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type ReusableResponses400Response = BadrequestResponse @@ -693,6 +720,7 @@ type TextExampleResponseObject interface { type TextExample200TextResponse string func (response TextExample200TextResponse) VisitTextExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -730,6 +758,7 @@ type UnknownExample200Videomp4Response struct { } func (response UnknownExample200Videomp4Response) VisitUnknownExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "video/mp4") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -775,6 +804,7 @@ type UnspecifiedContentType200VideoResponse struct { } func (response UnspecifiedContentType200VideoResponse) VisitUnspecifiedContentTypeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", response.ContentType) if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -831,15 +861,15 @@ type URLEncodedExampleResponseObject interface { type URLEncodedExample200FormdataResponse Example func (response URLEncodedExample200FormdataResponse) VisitURLEncodedExampleResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type URLEncodedExample400Response = BadrequestResponse @@ -878,12 +908,17 @@ type HeadersExample200JSONResponse struct { } func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type HeadersExample400Response = BadrequestResponse @@ -921,12 +956,17 @@ type UnionExample200ApplicationAlternativePlusJSONResponse struct { } func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnionExampleResponse(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/alternative+json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type UnionExample200JSONResponse struct { @@ -937,12 +977,17 @@ type UnionExample200JSONResponse struct { } func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body.union) + _, err := buf.WriteTo(w) + return err } type UnionExample400Response = BadrequestResponse diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index a141223fc5..c4cf39d483 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -504,10 +504,15 @@ type JSONExampleResponseObject interface { type JSONExample200JSONResponse Example func (response JSONExample200JSONResponse) VisitJSONExampleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type JSONExample400Response = BadrequestResponse @@ -538,6 +543,7 @@ type MultipartExample200MultipartResponse func(writer *multipart.Writer) error func (response MultipartExample200MultipartResponse) VisitMultipartExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -573,6 +579,7 @@ type MultipartRelatedExample200MultipartResponse func(writer *multipart.Writer) func (response MultipartRelatedExample200MultipartResponse) VisitMultipartRelatedExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) @@ -611,24 +618,29 @@ type MultipleRequestAndResponseTypesResponseObject interface { type MultipleRequestAndResponseTypes200JSONResponse Example func (response MultipleRequestAndResponseTypes200JSONResponse) VisitMultipleRequestAndResponseTypesResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type MultipleRequestAndResponseTypes200FormdataResponse Example func (response MultipleRequestAndResponseTypes200FormdataResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type MultipleRequestAndResponseTypes200ImagepngResponse struct { @@ -637,6 +649,7 @@ type MultipleRequestAndResponseTypes200ImagepngResponse struct { } func (response MultipleRequestAndResponseTypes200ImagepngResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "image/png") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -654,6 +667,7 @@ type MultipleRequestAndResponseTypes200MultipartResponse func(writer *multipart. func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -664,6 +678,7 @@ func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipl type MultipleRequestAndResponseTypes200TextResponse string func (response MultipleRequestAndResponseTypes200TextResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -689,10 +704,15 @@ type RequiredJSONBodyResponseObject interface { type RequiredJSONBody200JSONResponse Example func (response RequiredJSONBody200JSONResponse) VisitRequiredJSONBodyResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type RequiredJSONBody400Response = BadrequestResponse @@ -722,6 +742,7 @@ type RequiredTextBodyResponseObject interface { type RequiredTextBody200TextResponse string func (response RequiredTextBody200TextResponse) VisitRequiredTextBodyResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -756,6 +777,7 @@ type ReservedGoKeywordParametersResponseObject interface { type ReservedGoKeywordParameters200TextResponse string func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -774,12 +796,17 @@ type ReusableResponsesResponseObject interface { type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type ReusableResponses400Response = BadrequestResponse @@ -809,6 +836,7 @@ type TextExampleResponseObject interface { type TextExample200TextResponse string func (response TextExample200TextResponse) VisitTextExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -846,6 +874,7 @@ type UnknownExample200Videomp4Response struct { } func (response UnknownExample200Videomp4Response) VisitUnknownExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "video/mp4") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -891,6 +920,7 @@ type UnspecifiedContentType200VideoResponse struct { } func (response UnspecifiedContentType200VideoResponse) VisitUnspecifiedContentTypeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", response.ContentType) if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -947,15 +977,15 @@ type URLEncodedExampleResponseObject interface { type URLEncodedExample200FormdataResponse Example func (response URLEncodedExample200FormdataResponse) VisitURLEncodedExampleResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type URLEncodedExample400Response = BadrequestResponse @@ -994,12 +1024,17 @@ type HeadersExample200JSONResponse struct { } func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type HeadersExample400Response = BadrequestResponse @@ -1037,12 +1072,17 @@ type UnionExample200ApplicationAlternativePlusJSONResponse struct { } func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnionExampleResponse(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/alternative+json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type UnionExample200JSONResponse struct { @@ -1053,12 +1093,17 @@ type UnionExample200JSONResponse struct { } func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body.union) + _, err := buf.WriteTo(w) + return err } type UnionExample400Response = BadrequestResponse diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 2d6b8642ee..99160f5f0b 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -499,10 +499,15 @@ type JSONExampleResponseObject interface { type JSONExample200JSONResponse Example func (response JSONExample200JSONResponse) VisitJSONExampleResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type JSONExample400Response = BadrequestResponse @@ -533,6 +538,7 @@ type MultipartExample200MultipartResponse func(writer *multipart.Writer) error func (response MultipartExample200MultipartResponse) VisitMultipartExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -568,6 +574,7 @@ type MultipartRelatedExample200MultipartResponse func(writer *multipart.Writer) func (response MultipartRelatedExample200MultipartResponse) VisitMultipartRelatedExampleResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", mime.FormatMediaType("multipart/related", map[string]string{"boundary": writer.Boundary()})) w.WriteHeader(200) @@ -606,24 +613,29 @@ type MultipleRequestAndResponseTypesResponseObject interface { type MultipleRequestAndResponseTypes200JSONResponse Example func (response MultipleRequestAndResponseTypes200JSONResponse) VisitMultipleRequestAndResponseTypesResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type MultipleRequestAndResponseTypes200FormdataResponse Example func (response MultipleRequestAndResponseTypes200FormdataResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type MultipleRequestAndResponseTypes200ImagepngResponse struct { @@ -632,6 +644,7 @@ type MultipleRequestAndResponseTypes200ImagepngResponse struct { } func (response MultipleRequestAndResponseTypes200ImagepngResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "image/png") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -649,6 +662,7 @@ type MultipleRequestAndResponseTypes200MultipartResponse func(writer *multipart. func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { writer := multipart.NewWriter(w) + w.Header().Set("Content-Type", writer.FormDataContentType()) w.WriteHeader(200) @@ -659,6 +673,7 @@ func (response MultipleRequestAndResponseTypes200MultipartResponse) VisitMultipl type MultipleRequestAndResponseTypes200TextResponse string func (response MultipleRequestAndResponseTypes200TextResponse) VisitMultipleRequestAndResponseTypesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -684,10 +699,15 @@ type RequiredJSONBodyResponseObject interface { type RequiredJSONBody200JSONResponse Example func (response RequiredJSONBody200JSONResponse) VisitRequiredJSONBodyResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type RequiredJSONBody400Response = BadrequestResponse @@ -717,6 +737,7 @@ type RequiredTextBodyResponseObject interface { type RequiredTextBody200TextResponse string func (response RequiredTextBody200TextResponse) VisitRequiredTextBodyResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -751,6 +772,7 @@ type ReservedGoKeywordParametersResponseObject interface { type ReservedGoKeywordParameters200TextResponse string func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -769,12 +791,17 @@ type ReusableResponsesResponseObject interface { type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type ReusableResponses400Response = BadrequestResponse @@ -804,6 +831,7 @@ type TextExampleResponseObject interface { type TextExample200TextResponse string func (response TextExample200TextResponse) VisitTextExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/plain") w.WriteHeader(200) @@ -841,6 +869,7 @@ type UnknownExample200Videomp4Response struct { } func (response UnknownExample200Videomp4Response) VisitUnknownExampleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "video/mp4") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -886,6 +915,7 @@ type UnspecifiedContentType200VideoResponse struct { } func (response UnspecifiedContentType200VideoResponse) VisitUnspecifiedContentTypeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", response.ContentType) if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) @@ -942,15 +972,15 @@ type URLEncodedExampleResponseObject interface { type URLEncodedExample200FormdataResponse Example func (response URLEncodedExample200FormdataResponse) VisitURLEncodedExampleResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - w.WriteHeader(200) - if form, err := runtime.MarshalForm(response, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm(response, nil) + if err != nil { return err } + w.Header().Set("Content-Type", "application/x-www-form-urlencoded") + w.WriteHeader(200) + _, err = w.Write([]byte(form.Encode())) + return err } type URLEncodedExample400Response = BadrequestResponse @@ -989,12 +1019,17 @@ type HeadersExample200JSONResponse struct { } func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(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") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type HeadersExample400Response = BadrequestResponse @@ -1032,12 +1067,17 @@ type UnionExample200ApplicationAlternativePlusJSONResponse struct { } func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnionExampleResponse(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/alternative+json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type UnionExample200JSONResponse struct { @@ -1048,12 +1088,17 @@ type UnionExample200JSONResponse struct { } func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response.Body.union); err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) w.WriteHeader(200) - - return json.NewEncoder(w).Encode(response.Body.union) + _, err := buf.WriteTo(w) + return err } type UnionExample400Response = BadrequestResponse diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 62f3d4d9c6..ab56514e8a 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -74,40 +74,58 @@ {{if eq .NameTag "Multipart" -}} writer := multipart.NewWriter(w) {{end -}} - w.Header().Set("Content-Type", {{if eq .NameTag "Multipart"}}{{if eq .ContentType "multipart/form-data"}}writer.FormDataContentType(){{else}}mime.FormatMediaType("{{.ContentType}}", map[string]string{"boundary": writer.Boundary()}){{end}}{{else if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) - {{if not .IsSupported -}} - if response.ContentLength != 0 { - w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) - } - {{end -}} - {{range $headers -}} - w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) - {{end -}} - w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) {{$hasBodyVar := or ($hasHeaders) (not $fixedStatusCode) (not .IsSupported)}} {{if .IsJSON -}} - {{$hasUnionElements := ne 0 (len .Schema.UnionElements)}} - return json.NewEncoder(w).Encode(response{{if $hasBodyVar}}.Body{{end}}{{if $hasUnionElements}}.union{{end}}) - {{else if eq .NameTag "Text" -}} - _, err := w.Write([]byte({{if $hasBodyVar}}response.Body{{else}}response{{end}})) + {{$hasUnionElements := ne 0 (len .Schema.UnionElements) -}} + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response{{if $hasBodyVar}}.Body{{end}}{{if $hasUnionElements}}.union{{end}}); err != nil { + return err + } + w.Header().Set("Content-Type", {{if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) + {{range $headers -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} + w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) + _, err := buf.WriteTo(w) return err {{else if eq .NameTag "Formdata" -}} - if form, err := runtime.MarshalForm({{if $hasBodyVar}}response.Body{{else}}response{{end}}, nil); err != nil { - return err - } else { - _, err := w.Write([]byte(form.Encode())) + form, err := runtime.MarshalForm({{if $hasBodyVar}}response.Body{{else}}response{{end}}, nil) + if err != nil { return err } - {{else if eq .NameTag "Multipart" -}} - defer writer.Close() - return {{if $hasBodyVar}}response.Body{{else}}response{{end}}(writer); - {{else -}} - if closer, ok := response.Body.(io.ReadCloser); ok { - defer closer.Close() - } - _, err := io.Copy(w, response.Body) + w.Header().Set("Content-Type", {{if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) + {{range $headers -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} + w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) + _, err = w.Write([]byte(form.Encode())) return err - {{end}}{{/* if eq .NameTag "JSON" */ -}} + {{else -}} + w.Header().Set("Content-Type", {{if eq .NameTag "Multipart"}}{{if eq .ContentType "multipart/form-data"}}writer.FormDataContentType(){{else}}mime.FormatMediaType("{{.ContentType}}", map[string]string{"boundary": writer.Boundary()}){{end}}{{else if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) + {{if not .IsSupported -}} + if response.ContentLength != 0 { + w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) + } + {{end -}} + {{range $headers -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} + w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) + + {{if eq .NameTag "Text" -}} + _, err := w.Write([]byte({{if $hasBodyVar}}response.Body{{else}}response{{end}})) + return err + {{else if eq .NameTag "Multipart" -}} + defer writer.Close() + return {{if $hasBodyVar}}response.Body{{else}}response{{end}}(writer); + {{else -}} + if closer, ok := response.Body.(io.ReadCloser); ok { + defer closer.Close() + } + _, err := io.Copy(w, response.Body) + return err + {{end}}{{/* if eq .NameTag "Text" */ -}} + {{end}}{{/* if .IsJSON */ -}} } {{end}} From 524f05360eb0c01b05cb09da78450404712d1adc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 10:50:43 -0800 Subject: [PATCH 10/62] chore(deps): update release-drafter/release-drafter action to v6.3.0 (.github/workflows) (#2282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 7b03a27d7a..36d0c96320 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@6db134d15f3909ccc9eefd369f02bd1e9cffdf97 # v6.2.0 + - uses: release-drafter/release-drafter@00ce30b0ce8a4d67bccfca59421cdf6c55dd0784 # v6.3.0 with: name: next tag: next From e7059640da248633d129ec38c17fdc982396bcdb Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Thu, 12 Mar 2026 08:10:39 +0000 Subject: [PATCH 11/62] fix(client): correctly marshal `text/plain` requests (#1975) * fix(client): correctly marshal `text/plain` requests As noted in #1914, there are cases where trying to interact with a `text/plain` endpoint that requires input, for instance when receiving a UUID, may not render correctly. We should first check if the type is a `Stringer`, aka has a `String()` method, and use that - otherwise use `fmt.Sprintf("%v", ...)` to generate a string type. Via [0], we can make sure that we wrap the generated type in an empty `interface`, so we can perform the type assertion. This also adds a test case to validate the functionality for: - a UUID, which has a `String()` method - a `float32`, which is a primitive datatype that needs to use `fmt.Sprintf` Co-authored-by: claude-sonnet:3.7-thinking Closes #1914. [0]: https://www.jvt.me/posts/2025/05/10/go-type-assertion-concrete/ * fix(client): add three-tier text/plain body marshaling for #1914 For text/plain request bodies, the generated client code now: 1. Checks if the body type implements fmt.Stringer and uses String() 2. Falls back to fmt.Sprintf("%v", body) for primitive types 3. Returns an error for complex types (objects, arrays, composed schemas), directing the user to implement a String() method Adds Schema.IsPrimitive() to distinguish primitive OpenAPI types (string, integer, number, boolean) from complex ones at codegen time. Closes #1914. Co-Authored-By: Claude Sonnet 4.6 * Apply suggestion from @gaiaz-iusipov Co-authored-by: Gaiaz Iusipov * Update generated files --------- Co-authored-by: claude-sonnet:3.7-thinking Co-authored-by: Jamie Tanna Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Marcin Romaszewicz Co-authored-by: Gaiaz Iusipov --- internal/test/issues/issue-1914/cfg.yaml | 6 + internal/test/issues/issue-1914/client.gen.go | 401 ++++++++++++++++++ .../test/issues/issue-1914/client_test.go | 44 ++ internal/test/issues/issue-1914/generate.go | 3 + internal/test/issues/issue-1914/spec.yaml | 19 + .../test/strict-server/client/client.gen.go | 18 +- pkg/codegen/schema.go | 11 + pkg/codegen/templates/client.tmpl | 10 +- 8 files changed, 508 insertions(+), 4 deletions(-) create mode 100644 internal/test/issues/issue-1914/cfg.yaml create mode 100644 internal/test/issues/issue-1914/client.gen.go create mode 100644 internal/test/issues/issue-1914/client_test.go create mode 100644 internal/test/issues/issue-1914/generate.go create mode 100644 internal/test/issues/issue-1914/spec.yaml diff --git a/internal/test/issues/issue-1914/cfg.yaml b/internal/test/issues/issue-1914/cfg.yaml new file mode 100644 index 0000000000..1772f23885 --- /dev/null +++ b/internal/test/issues/issue-1914/cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: issue1914 +output: client.gen.go +generate: + client: true + models: true diff --git a/internal/test/issues/issue-1914/client.gen.go b/internal/test/issues/issue-1914/client.gen.go new file mode 100644 index 0000000000..bdbe1797d2 --- /dev/null +++ b/internal/test/issues/issue-1914/client.gen.go @@ -0,0 +1,401 @@ +// Package issue1914 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 issue1914 + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + openapi_types "github.com/oapi-codegen/runtime/types" +) + +// PostPetTextBody defines parameters for PostPet. +type PostPetTextBody = openapi_types.UUID + +// PostPet1234TextBody defines parameters for PostPet1234. +type PostPet1234TextBody = float32 + +// PostPetTextRequestBody defines body for PostPet for text/plain ContentType. +type PostPetTextRequestBody = PostPetTextBody + +// PostPet1234TextRequestBody defines body for PostPet1234 for text/plain ContentType. +type PostPet1234TextRequestBody = PostPet1234TextBody + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // PostPetWithBody request with any body + PostPetWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostPetWithTextBody(ctx context.Context, body PostPetTextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostPet1234WithBody request with any body + PostPet1234WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostPet1234WithTextBody(ctx context.Context, body PostPet1234TextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) PostPetWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostPetRequestWithBody(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 *Client) PostPetWithTextBody(ctx context.Context, body PostPetTextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostPetRequestWithTextBody(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 *Client) PostPet1234WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostPet1234RequestWithBody(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 *Client) PostPet1234WithTextBody(ctx context.Context, body PostPet1234TextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostPet1234RequestWithTextBody(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) +} + +// NewPostPetRequestWithTextBody calls the generic PostPet builder with text/plain body +func NewPostPetRequestWithTextBody(server string, body PostPetTextRequestBody) (*http.Request, error) { + var bodyReader io.Reader + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + bodyReader = strings.NewReader(fmt.Sprint(body)) + } + return NewPostPetRequestWithBody(server, "text/plain", bodyReader) +} + +// NewPostPetRequestWithBody generates requests for PostPet with any type of body +func NewPostPetRequestWithBody(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("/pet") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewPostPet1234RequestWithTextBody calls the generic PostPet1234 builder with text/plain body +func NewPostPet1234RequestWithTextBody(server string, body PostPet1234TextRequestBody) (*http.Request, error) { + var bodyReader io.Reader + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + bodyReader = strings.NewReader(fmt.Sprint(body)) + } + return NewPostPet1234RequestWithBody(server, "text/plain", bodyReader) +} + +// NewPostPet1234RequestWithBody generates requests for PostPet1234 with any type of body +func NewPostPet1234RequestWithBody(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("/pet/1234") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +func (c *Client) 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 *Client) 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 { + // PostPetWithBodyWithResponse request with any body + PostPetWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostPetResponse, error) + + PostPetWithTextBodyWithResponse(ctx context.Context, body PostPetTextRequestBody, reqEditors ...RequestEditorFn) (*PostPetResponse, error) + + // PostPet1234WithBodyWithResponse request with any body + PostPet1234WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostPet1234Response, error) + + PostPet1234WithTextBodyWithResponse(ctx context.Context, body PostPet1234TextRequestBody, reqEditors ...RequestEditorFn) (*PostPet1234Response, error) +} + +type PostPetResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostPetResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostPetResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostPet1234Response struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostPet1234Response) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostPet1234Response) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// PostPetWithBodyWithResponse request with arbitrary body returning *PostPetResponse +func (c *ClientWithResponses) PostPetWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostPetResponse, error) { + rsp, err := c.PostPetWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostPetResponse(rsp) +} + +func (c *ClientWithResponses) PostPetWithTextBodyWithResponse(ctx context.Context, body PostPetTextRequestBody, reqEditors ...RequestEditorFn) (*PostPetResponse, error) { + rsp, err := c.PostPetWithTextBody(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostPetResponse(rsp) +} + +// PostPet1234WithBodyWithResponse request with arbitrary body returning *PostPet1234Response +func (c *ClientWithResponses) PostPet1234WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostPet1234Response, error) { + rsp, err := c.PostPet1234WithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostPet1234Response(rsp) +} + +func (c *ClientWithResponses) PostPet1234WithTextBodyWithResponse(ctx context.Context, body PostPet1234TextRequestBody, reqEditors ...RequestEditorFn) (*PostPet1234Response, error) { + rsp, err := c.PostPet1234WithTextBody(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostPet1234Response(rsp) +} + +// ParsePostPetResponse parses an HTTP response from a PostPetWithResponse call +func ParsePostPetResponse(rsp *http.Response) (*PostPetResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostPetResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParsePostPet1234Response parses an HTTP response from a PostPet1234WithResponse call +func ParsePostPet1234Response(rsp *http.Response) (*PostPet1234Response, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostPet1234Response{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/issues/issue-1914/client_test.go b/internal/test/issues/issue-1914/client_test.go new file mode 100644 index 0000000000..282c589179 --- /dev/null +++ b/internal/test/issues/issue-1914/client_test.go @@ -0,0 +1,44 @@ +package issue1914 + +import ( + "io" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const testServer = "https://localhost" + +func TestNewPostPetRequestWithTextBody_CorrectlyMarshalsUUID(t *testing.T) { + id := uuid.New() + + req, err := NewPostPetRequestWithTextBody(testServer, id) + require.NoError(t, err) + + defer req.Body.Close() //nolint:errcheck + + bytes, err := io.ReadAll(req.Body) + require.NoError(t, err) + + require.NotEmpty(t, bytes) + + assert.Equal(t, id.String(), string(bytes)) +} + +func TestNewPostPet1234RequestWithTextBody_CorrectlyMarshalsFloat(t *testing.T) { + var id float32 = 1234.1 + + req, err := NewPostPet1234RequestWithTextBody(testServer, id) + require.NoError(t, err) + + defer req.Body.Close() //nolint:errcheck + + bytes, err := io.ReadAll(req.Body) + require.NoError(t, err) + + require.NotEmpty(t, bytes) + + assert.Equal(t, "1234.1", string(bytes)) +} diff --git a/internal/test/issues/issue-1914/generate.go b/internal/test/issues/issue-1914/generate.go new file mode 100644 index 0000000000..57e3c91587 --- /dev/null +++ b/internal/test/issues/issue-1914/generate.go @@ -0,0 +1,3 @@ +package issue1914 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=cfg.yaml spec.yaml diff --git a/internal/test/issues/issue-1914/spec.yaml b/internal/test/issues/issue-1914/spec.yaml new file mode 100644 index 0000000000..2f00f52f49 --- /dev/null +++ b/internal/test/issues/issue-1914/spec.yaml @@ -0,0 +1,19 @@ +openapi: 3.0.3 +paths: + /pet: + post: + description: Ensure that the `text/plain` format correctly handles coercing a UUID type to a string. + requestBody: + content: + text/plain: + schema: + type: string + format: uuid + /pet/1234: + post: + description: Ensure that the `text/plain` format correctly handles coercing a numerical type to a string. + requestBody: + content: + text/plain: + schema: + type: number diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index b189ff5adf..fa66382d70 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -642,7 +642,11 @@ func NewMultipleRequestAndResponseTypesRequestWithFormdataBody(server string, bo // NewMultipleRequestAndResponseTypesRequestWithTextBody calls the generic MultipleRequestAndResponseTypes builder with text/plain body func NewMultipleRequestAndResponseTypesRequestWithTextBody(server string, body MultipleRequestAndResponseTypesTextRequestBody) (*http.Request, error) { var bodyReader io.Reader - bodyReader = strings.NewReader(string(body)) + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + bodyReader = strings.NewReader(fmt.Sprint(body)) + } return NewMultipleRequestAndResponseTypesRequestWithBody(server, "text/plain", bodyReader) } @@ -718,7 +722,11 @@ func NewRequiredJSONBodyRequestWithBody(server string, contentType string, body // NewRequiredTextBodyRequestWithTextBody calls the generic RequiredTextBody builder with text/plain body func NewRequiredTextBodyRequestWithTextBody(server string, body RequiredTextBodyTextRequestBody) (*http.Request, error) { var bodyReader io.Reader - bodyReader = strings.NewReader(string(body)) + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + bodyReader = strings.NewReader(fmt.Sprint(body)) + } return NewRequiredTextBodyRequestWithBody(server, "text/plain", bodyReader) } @@ -828,7 +836,11 @@ func NewReusableResponsesRequestWithBody(server string, contentType string, body // NewTextExampleRequestWithTextBody calls the generic TextExample builder with text/plain body func NewTextExampleRequestWithTextBody(server string, body TextExampleTextRequestBody) (*http.Request, error) { var bodyReader io.Reader - bodyReader = strings.NewReader(string(body)) + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + bodyReader = strings.NewReader(fmt.Sprint(body)) + } return NewTextExampleRequestWithBody(server, "text/plain", bodyReader) } diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index ff72d23b6b..e6e1b2a3a1 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -42,6 +42,17 @@ type Schema struct { } +// IsPrimitive returns true if the schema represents a primitive OpenAPI type +// (string, integer, number, or boolean) as opposed to an object, array, or +// composed type. +func (s Schema) IsPrimitive() bool { + if s.OAPISchema == nil { + return false + } + t := s.OAPISchema.Type + return t.Is("string") || t.Is("integer") || t.Is("number") || t.Is("boolean") +} + func (s Schema) IsRef() bool { return s.RefType != "" } diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl index 24410dfae6..e172642825 100644 --- a/pkg/codegen/templates/client.tmpl +++ b/pkg/codegen/templates/client.tmpl @@ -148,7 +148,15 @@ func New{{$opid}}Request{{.Suffix}}(server string{{genParamArgs $pathParams}}{{i } bodyReader = strings.NewReader(bodyStr.Encode()) {{else if eq .NameTag "Text" -}} - bodyReader = strings.NewReader(string(body)) + if stringer, ok := interface{}(body).(fmt.Stringer); ok { + bodyReader = strings.NewReader(stringer.String()) + } else { + {{if .Schema.IsPrimitive -}} + bodyReader = strings.NewReader(fmt.Sprint(body)) + {{else -}} + return nil, fmt.Errorf("text/plain is not supported for complex types, define a String() method on {{.Schema.TypeDecl}} to marshal it as text") + {{end -}} + } {{end -}} return New{{$opid}}RequestWithBody(server{{genParamNames $pathParams}}{{if $hasParams}}, params{{end}}, "{{.ContentType}}", bodyReader) } From 8650f43d2ccd299534796c3ae510b197b1640ca9 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 12 Mar 2026 09:36:08 -0700 Subject: [PATCH 12/62] Fix typo in echo-v5 middleware import (#2285) Fixes: 2281 --- pkg/codegen/configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 0f35d13a90..1db5deff02 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -149,7 +149,7 @@ func (g GenerateOptions) RouterImports() []AdditionalImport { case g.Echo5Server: imports = append(imports, AdditionalImport{Package: "github.com/labstack/echo/v5"}) if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictecho5", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo/v5"}) + imports = append(imports, AdditionalImport{Alias: "strictecho5", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo-v5"}) } case g.ChiServer: imports = append(imports, AdditionalImport{Package: "github.com/go-chi/chi/v5"}) From 00a90b7a03f4cdc8bc8daf16eea6868b48c7d278 Mon Sep 17 00:00:00 2001 From: Ilia Rassadin <141235148+ilia-rassadin-rn@users.noreply.github.com> Date: Wed, 18 Mar 2026 13:37:12 +0100 Subject: [PATCH 13/62] fix(deps): update module github.com/getkin/kin-openapi to v0.134.0 (go.mod) (#2295) * fix: support kin-openapi v0.134.0 MappingRef type change In kin-openapi v0.134.0, Discriminator.Mapping changed from map[string]string to StringMap[MappingRef], where MappingRef is type MappingRef SchemaRef (a struct with a Ref string field). This caused a compile error in generateUnion where v (MappingRef) was compared directly against element.Ref (string). Fix by comparing v.Ref instead. Bump kin-openapi dependency to v0.134.0. * fix(deps): update module github.com/getkin/kin-openapi to v0.134.0 (go.mod) * fixup! fix(deps): update module github.com/getkin/kin-openapi to v0.134.0 (go.mod) --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jamie Tanna --- examples/authenticated-api/stdhttp/go.mod | 6 +++--- examples/authenticated-api/stdhttp/go.sum | 12 ++++++------ examples/go.mod | 6 +++--- examples/go.sum | 12 ++++++------ examples/minimal-server/stdhttp/go.mod | 6 +++--- examples/minimal-server/stdhttp/go.sum | 12 ++++++------ examples/petstore-expanded/echo-v5/go.mod | 6 +++--- examples/petstore-expanded/echo-v5/go.sum | 12 ++++++------ examples/petstore-expanded/stdhttp/go.mod | 6 +++--- examples/petstore-expanded/stdhttp/go.sum | 12 ++++++------ go.mod | 6 +++--- go.sum | 12 ++++++------ internal/test/go.mod | 6 +++--- internal/test/go.sum | 12 ++++++------ internal/test/strict-server/stdhttp/go.mod | 6 +++--- internal/test/strict-server/stdhttp/go.sum | 12 ++++++------ pkg/codegen/schema.go | 2 +- 17 files changed, 73 insertions(+), 73 deletions(-) diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index 64d200dc01..456ea79cc6 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/lestrrat-go/jwx v1.2.31 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 @@ -29,8 +29,8 @@ require ( github.com/lestrrat-go/option v1.0.1 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index 372e7efe62..190a8206db 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -13,8 +13,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -77,10 +77,10 @@ github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/go.mod b/examples/go.mod index 0b92bb2e87..998f23e291 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../ require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/gin-gonic/gin v1.11.0 github.com/go-chi/chi/v5 v5.2.5 github.com/gofiber/fiber/v2 v2.52.12 @@ -81,8 +81,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index 180de2d19d..49512be9b8 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -50,8 +50,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= @@ -207,10 +207,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/minimal-server/stdhttp/go.mod b/examples/minimal-server/stdhttp/go.mod index 98ad587fc4..acb4ea2c04 100644 --- a/examples/minimal-server/stdhttp/go.mod +++ b/examples/minimal-server/stdhttp/go.mod @@ -8,14 +8,14 @@ require github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-0000000000 require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.133.0 // indirect + github.com/getkin/kin-openapi v0.134.0 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect diff --git a/examples/minimal-server/stdhttp/go.sum b/examples/minimal-server/stdhttp/go.sum index e5ac6ef8cc..f2ff34e742 100644 --- a/examples/minimal-server/stdhttp/go.sum +++ b/examples/minimal-server/stdhttp/go.sum @@ -11,8 +11,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -54,10 +54,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod index 090320989f..09e9022013 100644 --- a/examples/petstore-expanded/echo-v5/go.mod +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -5,7 +5,7 @@ go 1.25.0 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/labstack/echo/v5 v5.0.4 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 @@ -24,8 +24,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum index 6cb9a23cb9..15fb93d7b0 100644 --- a/examples/petstore-expanded/echo-v5/go.sum +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -69,10 +69,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index 3922deb19e..481ce10be2 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 @@ -24,8 +24,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index 677ca72245..9976dfce36 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -69,10 +69,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/go.mod b/go.mod index ce84f98d4e..d6c392af11 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.3 toolchain go1.24.4 require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/speakeasy-api/openapi-overlay v0.10.2 github.com/stretchr/testify v1.11.1 golang.org/x/mod v0.33.0 @@ -23,8 +23,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/go.sum b/go.sum index 8e99a7a7fd..c7599ec79b 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -54,10 +54,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/internal/test/go.mod b/internal/test/go.mod index 6f70f67ca3..3883c7548e 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../ require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/gin-gonic/gin v1.11.0 github.com/go-chi/chi/v5 v5.2.5 github.com/gofiber/fiber/v2 v2.52.12 @@ -70,8 +70,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/internal/test/go.sum b/internal/test/go.sum index d4d3ba66ee..e4e6e813f1 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -48,8 +48,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= @@ -184,10 +184,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 19a1b1cfb5..443f10af94 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -7,7 +7,7 @@ replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ replace github.com/oapi-codegen/oapi-codegen/v2/internal/test => ../.. require ( - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.134.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/oapi-codegen/v2/internal/test v0.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 @@ -25,8 +25,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect + github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 4680d9a4bb..5ba1c74b30 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= +github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -65,10 +65,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= +github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= +github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index e6e1b2a3a1..799e327dea 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -897,7 +897,7 @@ func generateUnion(outSchema *Schema, elements openapi3.SchemaRefs, discriminato // Explicit mapping. var mapped bool for k, v := range discriminator.Mapping { - if v == element.Ref { + if v.Ref == element.Ref { outSchema.Discriminator.Mapping[k] = elementSchema.GoType mapped = true } From 28e3bc133939a35aa781eb76b331734685e31e00 Mon Sep 17 00:00:00 2001 From: Yata <84038514+YATAHAKI@users.noreply.github.com> Date: Mon, 23 Mar 2026 21:42:52 +0300 Subject: [PATCH 14/62] fix: getting cookie in fiber middleware (#2062) --- pkg/codegen/templates/fiber/fiber-middleware.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index eab735e5e6..dc48266696 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -127,7 +127,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{range .CookieParams}} var cookie string - if cookie = c.Cookies("{{.ParamName}}"); cookie == "" { + if cookie = c.Cookies("{{.ParamName}}"); cookie != "" { {{- if .IsPassThrough}} params.{{.GoName}} = {{if .HasOptionalPointer}}}&{{end}}cookie From fc65e09d0015f9b132ace66ac74bad2e0d0cb585 Mon Sep 17 00:00:00 2001 From: Kazusa Sugeno <52691115+imsugeno@users.noreply.github.com> Date: Tue, 24 Mar 2026 04:30:15 +0900 Subject: [PATCH 15/62] feat: use http.MethodXXX constants instead of string literals in generated code (#2294) * feat: use http.MethodXXX constants instead of string literals Add httpMethodConstant template helper that converts HTTP method strings (e.g. "GET") to net/http constants (e.g. http.MethodGet) and apply it to the client, gorilla, and stdhttp templates. Refs #659 * chore: regenerate code with http.MethodXXX constants Run make generate to update all generated files with the new http.MethodXXX constants in place of string literals. --------- Co-authored-by: Marcin Romaszewicz --- .../authenticated-api/stdhttp/api/api.gen.go | 8 ++-- .../minimal-server/stdhttp/api/ping.gen.go | 2 +- .../stdhttp/api/petstore.gen.go | 8 ++-- .../test/any_of/codegen/inline/openapi.gen.go | 2 +- .../any_of/codegen/ref_schema/openapi.gen.go | 2 +- internal/test/any_of/param/param.gen.go | 2 +- internal/test/client/client.gen.go | 16 +++---- internal/test/issues/issue-1039/client.gen.go | 2 +- internal/test/issues/issue-1087/api.gen.go | 2 +- internal/test/issues/issue-1180/issue.gen.go | 2 +- .../test/issues/issue-1182/pkg1/pkg1.gen.go | 2 +- .../test/issues/issue-1189/issue1189.gen.go | 2 +- .../issue-1208-1209/issue-multi-json.gen.go | 2 +- .../test/issues/issue-1212/pkg1/pkg1.gen.go | 2 +- .../test/issues/issue-1298/issue1298.gen.go | 2 +- .../issue-1378/bionicle/bionicle.gen.go | 2 +- .../issue-1378/fooservice/fooservice.gen.go | 2 +- .../test/issues/issue-1397/issue1397.gen.go | 2 +- .../issue-1529/strict-echo/issue1529.gen.go | 2 +- .../issue-1529/strict-fiber/issue1529.gen.go | 2 +- .../issue-1529/strict-iris/issue1529.gen.go | 2 +- internal/test/issues/issue-1676/ping.gen.go | 2 +- internal/test/issues/issue-1914/client.gen.go | 4 +- .../test/issues/issue-1963/issue1963.gen.go | 10 ++--- .../issues/issue-2031/prefer/issue2031.gen.go | 2 +- .../test/issues/issue-2190/issue2190.gen.go | 4 +- .../test/issues/issue-2232/issue2232.gen.go | 2 +- .../test/issues/issue-2238/issue2238.gen.go | 2 +- internal/test/issues/issue-312/issue.gen.go | 4 +- internal/test/issues/issue-52/issue.gen.go | 2 +- .../issue-grab_import_names/issue.gen.go | 2 +- .../issue-illegal_enum_names/issue.gen.go | 2 +- internal/test/issues/issue240/client.gen.go | 4 +- .../name_conflict_resolution.gen.go | 36 ++++++++-------- .../name_normalizer.gen.go | 4 +- .../name_normalizer.gen.go | 4 +- .../name_normalizer.gen.go | 4 +- .../to-camel-case/name_normalizer.gen.go | 4 +- .../unset/name_normalizer.gen.go | 4 +- internal/test/parameters/parameters.gen.go | 42 +++++++++---------- internal/test/schemas/schemas.gen.go | 20 ++++----- .../test/strict-server/client/client.gen.go | 28 ++++++------- .../test/strict-server/gorilla/server.gen.go | 28 ++++++------- .../test/strict-server/stdhttp/server.gen.go | 28 ++++++------- pkg/codegen/template_helpers.go | 26 ++++++++++++ pkg/codegen/templates/client.tmpl | 2 +- .../templates/gorilla/gorilla-register.tmpl | 2 +- .../templates/stdhttp/std-http-handler.tmpl | 2 +- 48 files changed, 184 insertions(+), 158 deletions(-) diff --git a/examples/authenticated-api/stdhttp/api/api.gen.go b/examples/authenticated-api/stdhttp/api/api.gen.go index bf3af4b293..da76ee17b2 100644 --- a/examples/authenticated-api/stdhttp/api/api.gen.go +++ b/examples/authenticated-api/stdhttp/api/api.gen.go @@ -188,7 +188,7 @@ func NewListThingsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -226,7 +226,7 @@ func NewAddThingRequestWithBody(server string, contentType string, body io.Reade return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -589,8 +589,8 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/things", wrapper.ListThings) - m.HandleFunc("POST "+options.BaseURL+"/things", wrapper.AddThing) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/things", wrapper.ListThings) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/things", wrapper.AddThing) return m } diff --git a/examples/minimal-server/stdhttp/api/ping.gen.go b/examples/minimal-server/stdhttp/api/ping.gen.go index 794f8d817f..0b1984332e 100644 --- a/examples/minimal-server/stdhttp/api/ping.gen.go +++ b/examples/minimal-server/stdhttp/api/ping.gen.go @@ -165,7 +165,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/ping", wrapper.GetPing) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/ping", wrapper.GetPing) return m } diff --git a/examples/petstore-expanded/stdhttp/api/petstore.gen.go b/examples/petstore-expanded/stdhttp/api/petstore.gen.go index 4f0c52be9d..1581d7705f 100644 --- a/examples/petstore-expanded/stdhttp/api/petstore.gen.go +++ b/examples/petstore-expanded/stdhttp/api/petstore.gen.go @@ -305,10 +305,10 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/pets", wrapper.FindPets) - m.HandleFunc("POST "+options.BaseURL+"/pets", wrapper.AddPet) - m.HandleFunc("DELETE "+options.BaseURL+"/pets/{id}", wrapper.DeletePet) - m.HandleFunc("GET "+options.BaseURL+"/pets/{id}", wrapper.FindPetByID) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/pets", wrapper.FindPets) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/pets", wrapper.AddPet) + m.HandleFunc(http.MethodDelete+" "+options.BaseURL+"/pets/{id}", wrapper.DeletePet) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/pets/{id}", wrapper.FindPetByID) return m } diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index 4179ed9495..3f85d9bc2f 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -156,7 +156,7 @@ func NewGetPetsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/any_of/codegen/ref_schema/openapi.gen.go b/internal/test/any_of/codegen/ref_schema/openapi.gen.go index d255052757..05d763e6ac 100644 --- a/internal/test/any_of/codegen/ref_schema/openapi.gen.go +++ b/internal/test/any_of/codegen/ref_schema/openapi.gen.go @@ -255,7 +255,7 @@ func NewGetPetsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/any_of/param/param.gen.go b/internal/test/any_of/param/param.gen.go index 483228d045..2a082006cc 100644 --- a/internal/test/any_of/param/param.gen.go +++ b/internal/test/any_of/param/param.gen.go @@ -319,7 +319,7 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, err queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/client/client.gen.go b/internal/test/client/client.gen.go index 17135a2ea7..13fe998b9a 100644 --- a/internal/test/client/client.gen.go +++ b/internal/test/client/client.gen.go @@ -305,7 +305,7 @@ func NewPostBothRequestWithBody(server string, contentType string, body io.Reade return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -334,7 +334,7 @@ func NewGetBothRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -372,7 +372,7 @@ func NewPostJsonRequestWithBody(server string, contentType string, body io.Reade return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -401,7 +401,7 @@ func NewGetJsonRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -428,7 +428,7 @@ func NewPostOtherRequestWithBody(server string, contentType string, body io.Read return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -457,7 +457,7 @@ func NewGetOtherRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -484,7 +484,7 @@ func NewGetJsonWithTrailingSlashRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -522,7 +522,7 @@ func NewPostVendorJsonRequestWithBody(server string, contentType string, body io return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1039/client.gen.go b/internal/test/issues/issue-1039/client.gen.go index 3114f29862..43cca8d279 100644 --- a/internal/test/issues/issue-1039/client.gen.go +++ b/internal/test/issues/issue-1039/client.gen.go @@ -147,7 +147,7 @@ func NewExamplePatchRequestWithBody(server string, contentType string, body io.R return nil, err } - req, err := http.NewRequest("PATCH", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPatch, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1087/api.gen.go b/internal/test/issues/issue-1087/api.gen.go index 7c154d9115..cf944315f5 100644 --- a/internal/test/issues/issue-1087/api.gen.go +++ b/internal/test/issues/issue-1087/api.gen.go @@ -144,7 +144,7 @@ func NewGetThingsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1180/issue.gen.go b/internal/test/issues/issue-1180/issue.gen.go index 26e358477a..dd7f244904 100644 --- a/internal/test/issues/issue-1180/issue.gen.go +++ b/internal/test/issues/issue-1180/issue.gen.go @@ -135,7 +135,7 @@ func NewGetSimplePrimitiveRequest(server string, param string) (*http.Request, e return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go index 0b01c5738e..4773438107 100644 --- a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go @@ -129,7 +129,7 @@ func NewTestGetRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1189/issue1189.gen.go b/internal/test/issues/issue-1189/issue1189.gen.go index c6e0579fd5..8b0aa4c209 100644 --- a/internal/test/issues/issue-1189/issue1189.gen.go +++ b/internal/test/issues/issue-1189/issue1189.gen.go @@ -339,7 +339,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index c93e087717..50ec7337a5 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -145,7 +145,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index d2922a4a85..50244c424f 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -131,7 +131,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1298/issue1298.gen.go b/internal/test/issues/issue-1298/issue1298.gen.go index 2e5a48dc57..a45d921e58 100644 --- a/internal/test/issues/issue-1298/issue1298.gen.go +++ b/internal/test/issues/issue-1298/issue1298.gen.go @@ -160,7 +160,7 @@ func NewTestRequestWithBody(server string, contentType string, body io.Reader) ( return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), body) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index c809c52904..c18418eaef 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -184,7 +184,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/bionicle/{name}", wrapper.GetBionicleName).Methods("GET") + r.HandleFunc(options.BaseURL+"/bionicle/{name}", wrapper.GetBionicleName).Methods(http.MethodGet) return r } diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index a6416cfdf2..966de191e5 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -177,7 +177,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/bionicle/{name}", wrapper.GetBionicleName).Methods("GET") + r.HandleFunc(options.BaseURL+"/bionicle/{name}", wrapper.GetBionicleName).Methods(http.MethodGet) return r } diff --git a/internal/test/issues/issue-1397/issue1397.gen.go b/internal/test/issues/issue-1397/issue1397.gen.go index 11bc883db2..a799293922 100644 --- a/internal/test/issues/issue-1397/issue1397.gen.go +++ b/internal/test/issues/issue-1397/issue1397.gen.go @@ -201,7 +201,7 @@ func NewTestRequestWithBody(server string, contentType string, body io.Reader) ( return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), body) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index 46655a12d3..d392436a89 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -132,7 +132,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index e1324845b6..f4fe591c04 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -131,7 +131,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go index a214576e80..6d03eef9ce 100644 --- a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go @@ -132,7 +132,7 @@ func NewTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1676/ping.gen.go b/internal/test/issues/issue-1676/ping.gen.go index 19a354080a..53fa480501 100644 --- a/internal/test/issues/issue-1676/ping.gen.go +++ b/internal/test/issues/issue-1676/ping.gen.go @@ -155,7 +155,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods("GET") + r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods(http.MethodGet) return r } diff --git a/internal/test/issues/issue-1914/client.gen.go b/internal/test/issues/issue-1914/client.gen.go index bdbe1797d2..5628fff078 100644 --- a/internal/test/issues/issue-1914/client.gen.go +++ b/internal/test/issues/issue-1914/client.gen.go @@ -188,7 +188,7 @@ func NewPostPetRequestWithBody(server string, contentType string, body io.Reader return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -228,7 +228,7 @@ func NewPostPet1234RequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-1963/issue1963.gen.go b/internal/test/issues/issue-1963/issue1963.gen.go index c47fb4aba0..9c5b00bd9b 100644 --- a/internal/test/issues/issue-1963/issue1963.gen.go +++ b/internal/test/issues/issue-1963/issue1963.gen.go @@ -266,11 +266,11 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("POST "+options.BaseURL+"/binary", wrapper.BinaryEndpoint) - m.HandleFunc("POST "+options.BaseURL+"/formdata", wrapper.FormdataEndpoint) - m.HandleFunc("POST "+options.BaseURL+"/json", wrapper.JsonEndpoint) - m.HandleFunc("POST "+options.BaseURL+"/multipart", wrapper.MultipartEndpoint) - m.HandleFunc("POST "+options.BaseURL+"/text", wrapper.TextEndpoint) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/binary", wrapper.BinaryEndpoint) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/formdata", wrapper.FormdataEndpoint) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/json", wrapper.JsonEndpoint) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multipart", wrapper.MultipartEndpoint) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/text", wrapper.TextEndpoint) return m } diff --git a/internal/test/issues/issue-2031/prefer/issue2031.gen.go b/internal/test/issues/issue-2031/prefer/issue2031.gen.go index 6144c0b4be..2aeb2c4b88 100644 --- a/internal/test/issues/issue-2031/prefer/issue2031.gen.go +++ b/internal/test/issues/issue-2031/prefer/issue2031.gen.go @@ -149,7 +149,7 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, err queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-2190/issue2190.gen.go b/internal/test/issues/issue-2190/issue2190.gen.go index 409eba372f..d911a8474c 100644 --- a/internal/test/issues/issue-2190/issue2190.gen.go +++ b/internal/test/issues/issue-2190/issue2190.gen.go @@ -129,7 +129,7 @@ func NewGetTestRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -391,7 +391,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/v1/test", wrapper.GetTest) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/v1/test", wrapper.GetTest) return m } diff --git a/internal/test/issues/issue-2232/issue2232.gen.go b/internal/test/issues/issue-2232/issue2232.gen.go index 1820ba5f29..9b98648470 100644 --- a/internal/test/issues/issue-2232/issue2232.gen.go +++ b/internal/test/issues/issue-2232/issue2232.gen.go @@ -254,7 +254,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/v1/endpoint", wrapper.GetEndpoint) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/v1/endpoint", wrapper.GetEndpoint) return m } diff --git a/internal/test/issues/issue-2238/issue2238.gen.go b/internal/test/issues/issue-2238/issue2238.gen.go index 81f395ddfa..043529ebce 100644 --- a/internal/test/issues/issue-2238/issue2238.gen.go +++ b/internal/test/issues/issue-2238/issue2238.gen.go @@ -128,7 +128,7 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, err return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-312/issue.gen.go b/internal/test/issues/issue-312/issue.gen.go index 1686dac248..e49ab36cfe 100644 --- a/internal/test/issues/issue-312/issue.gen.go +++ b/internal/test/issues/issue-312/issue.gen.go @@ -189,7 +189,7 @@ func NewGetPetRequest(server string, petId string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -227,7 +227,7 @@ func NewValidatePetsRequestWithBody(server string, contentType string, body io.R return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go index f024999d6a..2c57dd3223 100644 --- a/internal/test/issues/issue-52/issue.gen.go +++ b/internal/test/issues/issue-52/issue.gen.go @@ -142,7 +142,7 @@ func NewExampleGetRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go index 99bfcd9548..ee161c40e9 100644 --- a/internal/test/issues/issue-grab_import_names/issue.gen.go +++ b/internal/test/issues/issue-grab_import_names/issue.gen.go @@ -138,7 +138,7 @@ func NewGetFooRequest(server string, params *GetFooParams) (*http.Request, error return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go index 0c29ab71eb..1da3d74579 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go +++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go @@ -173,7 +173,7 @@ func NewGetFooRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/issues/issue240/client.gen.go b/internal/test/issues/issue240/client.gen.go index 8a0a533589..2953b8ce4a 100644 --- a/internal/test/issues/issue240/client.gen.go +++ b/internal/test/issues/issue240/client.gen.go @@ -141,7 +141,7 @@ func NewGetClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func NewUpdateClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodPut, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go index 068f8e6d4a..fa5b29bc16 100644 --- a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -1052,7 +1052,7 @@ func NewListEntitiesRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1112,7 +1112,7 @@ func NewPostFooRequestWithBody(server string, params *PostFooParams, contentType queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1141,7 +1141,7 @@ func NewListItemsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1179,7 +1179,7 @@ func NewCreateItemRequestWithBody(server string, contentType string, body io.Rea return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1241,7 +1241,7 @@ func NewCreateOrderRequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1270,7 +1270,7 @@ func NewGetOutcomeRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1308,7 +1308,7 @@ func NewPostOutcomeRequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1348,7 +1348,7 @@ func NewSendPayloadRequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1388,7 +1388,7 @@ func NewCreatePetRequestWithBody(server string, contentType string, body io.Read return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1428,7 +1428,7 @@ func NewQueryRequestWithBody(server string, contentType string, body io.Reader) return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1457,7 +1457,7 @@ func NewGetQuxRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1495,7 +1495,7 @@ func NewPostQuxRequestWithBody(server string, contentType string, body io.Reader return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1524,7 +1524,7 @@ func NewGetRenamedSchemaRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1562,7 +1562,7 @@ func NewPostRenamedSchemaRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1631,7 +1631,7 @@ func NewPatchResourceRequestWithBody(server string, id string, contentType strin return nil, err } - req, err := http.NewRequest("PATCH", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPatch, queryURL.String(), body) if err != nil { return nil, err } @@ -1660,7 +1660,7 @@ func NewGetStatusRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1687,7 +1687,7 @@ func NewGetZapRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1725,7 +1725,7 @@ func NewPostZapRequestWithBody(server string, contentType string, body io.Reader return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go index 8d02762813..0b00613664 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go @@ -232,7 +232,7 @@ func NewGetHTTPPetRequest(server string, petID string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -498,7 +498,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHTTPPet).Methods("GET") + r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHTTPPet).Methods(http.MethodGet) return r } diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go index 206ddbf64d..93dc41ff9b 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go @@ -232,7 +232,7 @@ func NewGetHttpPetRequest(server string, petId string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -498,7 +498,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods("GET") + r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods(http.MethodGet) return r } diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go index 6cf9d6e7fe..935b805c1c 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go @@ -232,7 +232,7 @@ func NewGetHTTPPetRequest(server string, petID string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -498,7 +498,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHTTPPet).Methods("GET") + r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHTTPPet).Methods(http.MethodGet) return r } diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go index e34d1c4663..50478990af 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go @@ -232,7 +232,7 @@ func NewGetHttpPetRequest(server string, petId string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -498,7 +498,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods("GET") + r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods(http.MethodGet) return r } diff --git a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go index 17f65ad9ee..59d306d519 100644 --- a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go @@ -232,7 +232,7 @@ func NewGetHttpPetRequest(server string, petId string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -498,7 +498,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods("GET") + r.HandleFunc(options.BaseURL+"/api/pets/{petId}", wrapper.GetHttpPet).Methods(http.MethodGet) return r } diff --git a/internal/test/parameters/parameters.gen.go b/internal/test/parameters/parameters.gen.go index 5821715fc2..6b68f2fd25 100644 --- a/internal/test/parameters/parameters.gen.go +++ b/internal/test/parameters/parameters.gen.go @@ -568,7 +568,7 @@ func NewGetContentObjectRequest(server string, param ComplexObject) (*http.Reque return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -595,7 +595,7 @@ func NewGetCookieRequest(server string, params *GetCookieParams) (*http.Request, return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -768,7 +768,7 @@ func NewEnumParamsRequest(server string, params *EnumParamsParams) (*http.Reques queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -795,7 +795,7 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request, return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -923,7 +923,7 @@ func NewGetLabelExplodeArrayRequest(server string, param []int32) (*http.Request return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -957,7 +957,7 @@ func NewGetLabelExplodeObjectRequest(server string, param Object) (*http.Request return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -991,7 +991,7 @@ func NewGetLabelNoExplodeArrayRequest(server string, param []int32) (*http.Reque return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1025,7 +1025,7 @@ func NewGetLabelNoExplodeObjectRequest(server string, param Object) (*http.Reque return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1059,7 +1059,7 @@ func NewGetMatrixExplodeArrayRequest(server string, id []int32) (*http.Request, return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1093,7 +1093,7 @@ func NewGetMatrixExplodeObjectRequest(server string, id Object) (*http.Request, return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1127,7 +1127,7 @@ func NewGetMatrixNoExplodeArrayRequest(server string, id []int32) (*http.Request return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1161,7 +1161,7 @@ func NewGetMatrixNoExplodeObjectRequest(server string, id Object) (*http.Request return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1192,7 +1192,7 @@ func NewGetPassThroughRequest(server string, param string) (*http.Request, error return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1237,7 +1237,7 @@ func NewGetDeepObjectRequest(server string, params *GetDeepObjectParams) (*http. queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1408,7 +1408,7 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1442,7 +1442,7 @@ func NewGetSimpleExplodeArrayRequest(server string, param []int32) (*http.Reques return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1476,7 +1476,7 @@ func NewGetSimpleExplodeObjectRequest(server string, param Object) (*http.Reques return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1510,7 +1510,7 @@ func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Requ return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1544,7 +1544,7 @@ func NewGetSimpleNoExplodeObjectRequest(server string, param Object) (*http.Requ return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1578,7 +1578,7 @@ func NewGetSimplePrimitiveRequest(server string, param int32) (*http.Request, er return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -1609,7 +1609,7 @@ func NewGetStartingWithNumberRequest(server string, n1param string) (*http.Reque return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index f8293f4608..ad4e412d05 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -399,7 +399,7 @@ func NewEnsureEverythingIsReferencedRequest(server string) (*http.Request, error return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -426,7 +426,7 @@ func NewIssue1051Request(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -453,7 +453,7 @@ func NewIssue127Request(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -491,7 +491,7 @@ func NewIssue185RequestWithBody(server string, contentType string, body io.Reade return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), body) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), body) if err != nil { return nil, err } @@ -527,7 +527,7 @@ func NewIssue209Request(server string, str StringInPath) (*http.Request, error) return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -561,7 +561,7 @@ func NewIssue30Request(server string, pFallthrough string) (*http.Request, error return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -588,7 +588,7 @@ func NewGetIssues375Request(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -622,7 +622,7 @@ func NewIssue41Request(server string, n1param N5StartsWithNumber) (*http.Request return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -678,7 +678,7 @@ func NewIssue9RequestWithBody(server string, params *Issue9Params, contentType s queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("GET", queryURL.String(), body) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), body) if err != nil { return nil, err } @@ -707,7 +707,7 @@ func NewIssue975Request(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index fa66382d70..66eeb2014c 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -549,7 +549,7 @@ func NewJSONExampleRequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -578,7 +578,7 @@ func NewMultipartExampleRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -607,7 +607,7 @@ func NewMultipartRelatedExampleRequestWithBody(server string, contentType string return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -669,7 +669,7 @@ func NewMultipleRequestAndResponseTypesRequestWithBody(server string, contentTyp return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -709,7 +709,7 @@ func NewRequiredJSONBodyRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -749,7 +749,7 @@ func NewRequiredTextBodyRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -785,7 +785,7 @@ func NewReservedGoKeywordParametersRequest(server string, pType string) (*http.R return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -823,7 +823,7 @@ func NewReusableResponsesRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -863,7 +863,7 @@ func NewTextExampleRequestWithBody(server string, contentType string, body io.Re return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -892,7 +892,7 @@ func NewUnknownExampleRequestWithBody(server string, contentType string, body io return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -921,7 +921,7 @@ func NewUnspecifiedContentTypeRequestWithBody(server string, contentType string, return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -961,7 +961,7 @@ func NewURLEncodedExampleRequestWithBody(server string, contentType string, body return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1001,7 +1001,7 @@ func NewHeadersExampleRequestWithBody(server string, params *HeadersExampleParam return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -1065,7 +1065,7 @@ func NewUnionExampleRequestWithBody(server string, contentType string, body io.R return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index c4cf39d483..c27989b6c4 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -449,33 +449,33 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/json", wrapper.JSONExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/json", wrapper.JSONExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/multipart", wrapper.MultipartExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/multipart", wrapper.MultipartExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes).Methods("POST") + r.HandleFunc(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody).Methods("POST") + r.HandleFunc(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody).Methods("POST") + r.HandleFunc(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters).Methods("GET") + r.HandleFunc(options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters).Methods(http.MethodGet) - r.HandleFunc(options.BaseURL+"/reusable-responses", wrapper.ReusableResponses).Methods("POST") + r.HandleFunc(options.BaseURL+"/reusable-responses", wrapper.ReusableResponses).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/text", wrapper.TextExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/text", wrapper.TextExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/unknown", wrapper.UnknownExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/unknown", wrapper.UnknownExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType).Methods("POST") + r.HandleFunc(options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/urlencoded", wrapper.URLEncodedExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/urlencoded", wrapper.URLEncodedExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/with-headers", wrapper.HeadersExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/with-headers", wrapper.HeadersExample).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/with-union", wrapper.UnionExample).Methods("POST") + r.HandleFunc(options.BaseURL+"/with-union", wrapper.UnionExample).Methods(http.MethodPost) return r } diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 99160f5f0b..271fcdccd4 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -457,20 +457,20 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("POST "+options.BaseURL+"/json", wrapper.JSONExample) - m.HandleFunc("POST "+options.BaseURL+"/multipart", wrapper.MultipartExample) - m.HandleFunc("POST "+options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample) - m.HandleFunc("POST "+options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) - m.HandleFunc("POST "+options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) - m.HandleFunc("POST "+options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) - m.HandleFunc("GET "+options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters) - m.HandleFunc("POST "+options.BaseURL+"/reusable-responses", wrapper.ReusableResponses) - m.HandleFunc("POST "+options.BaseURL+"/text", wrapper.TextExample) - m.HandleFunc("POST "+options.BaseURL+"/unknown", wrapper.UnknownExample) - m.HandleFunc("POST "+options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType) - m.HandleFunc("POST "+options.BaseURL+"/urlencoded", wrapper.URLEncodedExample) - m.HandleFunc("POST "+options.BaseURL+"/with-headers", wrapper.HeadersExample) - m.HandleFunc("POST "+options.BaseURL+"/with-union", wrapper.UnionExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/json", wrapper.JSONExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multipart", wrapper.MultipartExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/reusable-responses", wrapper.ReusableResponses) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/text", wrapper.TextExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/unknown", wrapper.UnknownExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/urlencoded", wrapper.URLEncodedExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/with-headers", wrapper.HeadersExample) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/with-union", wrapper.UnionExample) return m } diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 19c533f1e6..819c5c5158 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -323,6 +323,31 @@ func genServerURLWithVariablesFunctionParams(goTypePrefix string, variables map[ return strings.Join(parts, ", ") } +// httpMethodConstant converts an HTTP method string (e.g. "GET") to the +// corresponding Go net/http constant (e.g. "http.MethodGet"). +func httpMethodConstant(method string) string { + switch method { + case "GET": + return "http.MethodGet" + case "POST": + return "http.MethodPost" + case "PUT": + return "http.MethodPut" + case "DELETE": + return "http.MethodDelete" + case "PATCH": + return "http.MethodPatch" + case "HEAD": + return "http.MethodHead" + case "OPTIONS": + return "http.MethodOptions" + case "TRACE": + return "http.MethodTrace" + default: + return fmt.Sprintf("%q", method) + } +} + // TemplateFunctions is passed to the template engine, and we can call each // function here by keyName from the template code. var TemplateFunctions = template.FuncMap{ @@ -355,4 +380,5 @@ var TemplateFunctions = template.FuncMap{ "toGoComment": StringWithTypeNameToGoComment, "genServerURLWithVariablesFunctionParams": genServerURLWithVariablesFunctionParams, + "httpMethodConstant": httpMethodConstant, } diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl index e172642825..d85ffb5631 100644 --- a/pkg/codegen/templates/client.tmpl +++ b/pkg/codegen/templates/client.tmpl @@ -235,7 +235,7 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr queryURL.RawQuery = queryValues.Encode() } {{end}}{{/* if .QueryParams */}} - req, err := http.NewRequest("{{.Method}}", queryURL.String(), {{if .HasBody}}body{{else}}nil{{end}}) + req, err := http.NewRequest({{.Method | httpMethodConstant}}, queryURL.String(), {{if .HasBody}}body{{else}}nil{{end}}) if err != nil { return nil, err } diff --git a/pkg/codegen/templates/gorilla/gorilla-register.tmpl b/pkg/codegen/templates/gorilla/gorilla-register.tmpl index b019e1dbbf..28e8ff2720 100644 --- a/pkg/codegen/templates/gorilla/gorilla-register.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-register.tmpl @@ -43,7 +43,7 @@ ErrorHandlerFunc: options.ErrorHandlerFunc, } {{end}} {{range .}} -r.HandleFunc(options.BaseURL+"{{.Path | swaggerUriToGorillaUri }}", wrapper.{{.OperationId}}).Methods("{{.Method }}") +r.HandleFunc(options.BaseURL+"{{.Path | swaggerUriToGorillaUri }}", wrapper.{{.OperationId}}).Methods({{.Method | httpMethodConstant}}) {{end}} return r } diff --git a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl index bed4685c74..2aa164ddfd 100644 --- a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl @@ -49,7 +49,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } {{end}} -{{range .}}m.HandleFunc("{{.Method }} "+options.BaseURL+"{{.Path | swaggerUriToStdHttpUri}}", wrapper.{{.OperationId}}) +{{range .}}m.HandleFunc({{.Method | httpMethodConstant}}+" "+options.BaseURL+"{{.Path | swaggerUriToStdHttpUri}}", wrapper.{{.OperationId}}) {{end}} return m } From 357f00c5149d41acf6f00ac157a957dca3d22457 Mon Sep 17 00:00:00 2001 From: Gaiaz Iusipov Date: Tue, 24 Mar 2026 03:40:22 +0800 Subject: [PATCH 16/62] fix(cli): remove unused `initialism-overrides` option (#2287) * fix(cli): remove unused `initialism-overrides` option Signed-off-by: Gaiaz Iusipov * test: update `TestGenerateDefaultOperationID` Signed-off-by: Gaiaz Iusipov --------- Signed-off-by: Gaiaz Iusipov Co-authored-by: Marcin Romaszewicz --- cmd/oapi-codegen/oapi-codegen.go | 4 ---- configuration-schema.json | 4 ---- pkg/codegen/codegen.go | 2 +- pkg/codegen/configuration.go | 2 -- pkg/codegen/operations.go | 13 +++---------- pkg/codegen/operations_test.go | 2 +- 6 files changed, 5 insertions(+), 22 deletions(-) diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go index 088821f5da..777697b7b8 100644 --- a/cmd/oapi-codegen/oapi-codegen.go +++ b/cmd/oapi-codegen/oapi-codegen.go @@ -58,7 +58,6 @@ var ( flagExcludeSchemas string flagResponseTypeSuffix string flagAliasTypes bool - flagInitialismOverrides bool ) type configuration struct { @@ -112,7 +111,6 @@ func main() { flag.StringVar(&flagExcludeSchemas, "exclude-schemas", "", "A comma separated list of schemas which must be excluded from generation.") flag.StringVar(&flagResponseTypeSuffix, "response-type-suffix", "", "The suffix used for responses types.") flag.BoolVar(&flagAliasTypes, "alias-types", false, "Alias type declarations if possible.") - flag.BoolVar(&flagInitialismOverrides, "initialism-overrides", false, "Use initialism overrides.") flag.Parse() @@ -459,8 +457,6 @@ func updateConfigFromFlags(cfg *configuration) error { cfg.OutputFile = flagOutputFile } - cfg.OutputOptions.InitialismOverrides = flagInitialismOverrides - return nil } diff --git a/configuration-schema.json b/configuration-schema.json index d25061e31b..ff325c1f6e 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -181,10 +181,6 @@ "type": "string", "description": "Override the default generated client type with the value" }, - "initialism-overrides": { - "type": "boolean", - "description": "Whether to use the initialism overrides" - }, "additional-initialisms": { "type": "array", "description": "AdditionalInitialisms defines additional initialisms to be used by the code generator. Has no effect unless the `name-normalizer` is set to `ToCamelCaseWithInitialisms`", diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 6aedce1805..44cfc6faf2 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -229,7 +229,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { } } - ops, err := OperationDefinitions(spec, opts.OutputOptions.InitialismOverrides) + ops, err := OperationDefinitions(spec) if err != nil { return "", fmt.Errorf("error creating operation definitions: %w", err) } diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 1db5deff02..d3e67a1b95 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -316,8 +316,6 @@ type OutputOptions struct { ResponseTypeSuffix string `yaml:"response-type-suffix,omitempty"` // Override the default generated client type with the value ClientTypeName string `yaml:"client-type-name,omitempty"` - // Whether to use the initialism overrides - InitialismOverrides bool `yaml:"initialism-overrides,omitempty"` // AdditionalInitialisms is a list of additional initialisms to use when generating names. // NOTE that this has no effect unless the `name-normalizer` is set to `ToCamelCaseWithInitialisms` AdditionalInitialisms []string `yaml:"additional-initialisms,omitempty"` diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 5d9f735506..beffe95751 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -602,16 +602,9 @@ func FilterParameterDefinitionByType(params []ParameterDefinition, in string) [] } // OperationDefinitions returns all operations for a swagger definition. -func OperationDefinitions(swagger *openapi3.T, initialismOverrides bool) ([]OperationDefinition, error) { +func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { var operations []OperationDefinition - var toCamelCaseFunc func(string) string - if initialismOverrides { - toCamelCaseFunc = ToCamelCaseWithInitialism - } else { - toCamelCaseFunc = ToCamelCase - } - if swagger == nil || swagger.Paths == nil { return operations, nil } @@ -639,7 +632,7 @@ func OperationDefinitions(swagger *openapi3.T, initialismOverrides bool) ([]Oper operationId := op.OperationID // We rely on OperationID to generate function names, it's required if operationId == "" { - operationId, err = generateDefaultOperationID(opName, requestPath, toCamelCaseFunc) + operationId, err = generateDefaultOperationID(opName, requestPath) if err != nil { return nil, fmt.Errorf("error generating default OperationID for %s/%s: %s", opName, requestPath, err) @@ -736,7 +729,7 @@ func OperationDefinitions(swagger *openapi3.T, initialismOverrides bool) ([]Oper return operations, nil } -func generateDefaultOperationID(opName string, requestPath string, toCamelCaseFunc func(string) string) (string, error) { +func generateDefaultOperationID(opName string, requestPath string) (string, error) { var operationId = strings.ToLower(opName) if opName == "" { diff --git a/pkg/codegen/operations_test.go b/pkg/codegen/operations_test.go index 77a54a8c25..0eff03e2c2 100644 --- a/pkg/codegen/operations_test.go +++ b/pkg/codegen/operations_test.go @@ -131,7 +131,7 @@ func TestGenerateDefaultOperationID(t *testing.T) { } for _, test := range suite { - got, err := generateDefaultOperationID(test.op, test.path, ToCamelCase) + got, err := generateDefaultOperationID(test.op, test.path) if err != nil { if !test.wantErr { t.Fatalf("did not expected error but got %v", err) From ddd9e9093462dbc6c9338196e7b3ed178e3d8ab7 Mon Sep 17 00:00:00 2001 From: lestrrat <49281+lestrrat@users.noreply.github.com> Date: Tue, 24 Mar 2026 05:44:36 +0900 Subject: [PATCH 17/62] update jwx to v3 (#2300) --- .../authenticated-api/echo/server/fake_jws.go | 23 +++++++------ .../echo/server/jwt_authenticator.go | 19 +++++------ examples/authenticated-api/stdhttp/go.mod | 17 ++++++---- examples/authenticated-api/stdhttp/go.sum | 34 ++++++++++--------- .../stdhttp/server/fake_jws.go | 23 +++++++------ .../stdhttp/server/jwt_authenticator.go | 19 +++++------ examples/go.mod | 14 ++++---- examples/go.sum | 30 ++++++++-------- 8 files changed, 92 insertions(+), 87 deletions(-) diff --git a/examples/authenticated-api/echo/server/fake_jws.go b/examples/authenticated-api/echo/server/fake_jws.go index 6eb3067d86..ce18dded1a 100644 --- a/examples/authenticated-api/echo/server/fake_jws.go +++ b/examples/authenticated-api/echo/server/fake_jws.go @@ -4,10 +4,10 @@ import ( "crypto/ecdsa" "fmt" - "github.com/lestrrat-go/jwx/jwa" - "github.com/lestrrat-go/jwx/jwk" - "github.com/lestrrat-go/jwx/jws" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v3/jwa" + "github.com/lestrrat-go/jwx/v3/jwk" + "github.com/lestrrat-go/jwx/v3/jws" + "github.com/lestrrat-go/jwx/v3/jwt" "github.com/oapi-codegen/oapi-codegen/v2/pkg/ecdsafile" ) @@ -46,14 +46,12 @@ func NewFakeAuthenticator() (*FakeAuthenticator, error) { } set := jwk.NewSet() - pubKey := jwk.NewECDSAPublicKey() - - err = pubKey.FromRaw(&privKey.PublicKey) + pubKey, err := jwk.Import(&privKey.PublicKey) if err != nil { return nil, fmt.Errorf("parsing jwk key: %w", err) } - err = pubKey.Set(jwk.AlgorithmKey, jwa.ES256) + err = pubKey.Set(jwk.AlgorithmKey, jwa.ES256()) if err != nil { return nil, fmt.Errorf("setting key algorithm: %w", err) } @@ -63,7 +61,10 @@ func NewFakeAuthenticator() (*FakeAuthenticator, error) { return nil, fmt.Errorf("setting key ID: %w", err) } - set.Add(pubKey) + err = set.AddKey(pubKey) + if err != nil { + return nil, fmt.Errorf("adding public key to key set: %w", err) + } return &FakeAuthenticator{PrivateKey: privKey, KeySet: set}, nil } @@ -78,7 +79,7 @@ func (f *FakeAuthenticator) ValidateJWS(jwsString string) (jwt.Token, error) { // SignToken takes a JWT and signs it with our private key, returning a JWS. func (f *FakeAuthenticator) SignToken(t jwt.Token) ([]byte, error) { hdr := jws.NewHeaders() - if err := hdr.Set(jws.AlgorithmKey, jwa.ES256); err != nil { + if err := hdr.Set(jws.AlgorithmKey, jwa.ES256()); err != nil { return nil, fmt.Errorf("setting algorithm: %w", err) } if err := hdr.Set(jws.TypeKey, "JWT"); err != nil { @@ -87,7 +88,7 @@ func (f *FakeAuthenticator) SignToken(t jwt.Token) ([]byte, error) { if err := hdr.Set(jws.KeyIDKey, KeyID); err != nil { return nil, fmt.Errorf("setting Key ID: %w", err) } - return jwt.Sign(t, jwa.ES256, f.PrivateKey, jwt.WithHeaders(hdr)) + return jwt.Sign(t, jwt.WithKey(jwa.ES256(), f.PrivateKey, jws.WithProtectedHeaders(hdr))) } // CreateJWSWithClaims is a helper function to create JWT's with the specified diff --git a/examples/authenticated-api/echo/server/jwt_authenticator.go b/examples/authenticated-api/echo/server/jwt_authenticator.go index c9d9a73a5a..ec11a2245b 100644 --- a/examples/authenticated-api/echo/server/jwt_authenticator.go +++ b/examples/authenticated-api/echo/server/jwt_authenticator.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3filter" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v3/jwt" middleware "github.com/oapi-codegen/echo-middleware" ) @@ -89,30 +89,27 @@ func Authenticate(v JWSValidator, ctx context.Context, input *openapi3filter.Aut // as a list under the "perms" claim, short for permissions, to keep the token // shorter. func GetClaimsFromToken(t jwt.Token) ([]string, error) { - rawPerms, found := t.Get(PermissionsClaim) - if !found { + if !t.Has(PermissionsClaim) { // If the perms aren't found, it means that the token has none, but it has // passed signature validation by now, so it's a valid token, so we return // the empty list. return make([]string, 0), nil } - // rawPerms will be an untyped JSON list, so we need to convert it to - // a string list. - rawList, ok := rawPerms.([]interface{}) - if !ok { - return nil, fmt.Errorf("'%s' claim is unexpected type'", PermissionsClaim) + var rawList []interface{} + if err := t.Get(PermissionsClaim, &rawList); err != nil { + return nil, fmt.Errorf("getting %q claim: %w", PermissionsClaim, err) } claims := make([]string, len(rawList)) - for i, rawClaim := range rawList { - var ok bool - claims[i], ok = rawClaim.(string) + claim, ok := rawClaim.(string) if !ok { return nil, fmt.Errorf("%s[%d] is not a string", PermissionsClaim, i) } + claims[i] = claim } + return claims, nil } diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index 456ea79cc6..f86436a306 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -6,7 +6,7 @@ replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( github.com/getkin/kin-openapi v0.134.0 - github.com/lestrrat-go/jwx v1.2.31 + github.com/lestrrat-go/jwx/v3 v3.0.13 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/testutil v1.1.0 @@ -22,25 +22,28 @@ require ( github.com/goccy/go-json v0.10.3 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/blackmagic v1.0.4 // indirect + github.com/lestrrat-go/dsig v1.0.0 // indirect + github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.2 // indirect + github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/segmentio/asm v1.2.1 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/valyala/fastjson v1.6.7 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.46.0 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index 190a8206db..0ad850b61a 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -53,19 +53,20 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA= +github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= +github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38= +github.com/lestrrat-go/dsig v1.0.0/go.mod h1:dEgoOYYEJvW6XGbLasr8TFcAxoWrKlbQvmJgCR0qkDo= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7gcrVVMFPOzY= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= -github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/httprc/v3 v3.0.2 h1:7u4HUaD0NQbf2/n5+fyp+T10hNCsAnwKfqn4A4Baif0= +github.com/lestrrat-go/httprc/v3 v3.0.2/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= +github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk= +github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU= +github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= +github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -95,11 +96,11 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= +github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= @@ -109,12 +110,13 @@ github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= +github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= @@ -123,8 +125,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= diff --git a/examples/authenticated-api/stdhttp/server/fake_jws.go b/examples/authenticated-api/stdhttp/server/fake_jws.go index 6eb3067d86..ce18dded1a 100644 --- a/examples/authenticated-api/stdhttp/server/fake_jws.go +++ b/examples/authenticated-api/stdhttp/server/fake_jws.go @@ -4,10 +4,10 @@ import ( "crypto/ecdsa" "fmt" - "github.com/lestrrat-go/jwx/jwa" - "github.com/lestrrat-go/jwx/jwk" - "github.com/lestrrat-go/jwx/jws" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v3/jwa" + "github.com/lestrrat-go/jwx/v3/jwk" + "github.com/lestrrat-go/jwx/v3/jws" + "github.com/lestrrat-go/jwx/v3/jwt" "github.com/oapi-codegen/oapi-codegen/v2/pkg/ecdsafile" ) @@ -46,14 +46,12 @@ func NewFakeAuthenticator() (*FakeAuthenticator, error) { } set := jwk.NewSet() - pubKey := jwk.NewECDSAPublicKey() - - err = pubKey.FromRaw(&privKey.PublicKey) + pubKey, err := jwk.Import(&privKey.PublicKey) if err != nil { return nil, fmt.Errorf("parsing jwk key: %w", err) } - err = pubKey.Set(jwk.AlgorithmKey, jwa.ES256) + err = pubKey.Set(jwk.AlgorithmKey, jwa.ES256()) if err != nil { return nil, fmt.Errorf("setting key algorithm: %w", err) } @@ -63,7 +61,10 @@ func NewFakeAuthenticator() (*FakeAuthenticator, error) { return nil, fmt.Errorf("setting key ID: %w", err) } - set.Add(pubKey) + err = set.AddKey(pubKey) + if err != nil { + return nil, fmt.Errorf("adding public key to key set: %w", err) + } return &FakeAuthenticator{PrivateKey: privKey, KeySet: set}, nil } @@ -78,7 +79,7 @@ func (f *FakeAuthenticator) ValidateJWS(jwsString string) (jwt.Token, error) { // SignToken takes a JWT and signs it with our private key, returning a JWS. func (f *FakeAuthenticator) SignToken(t jwt.Token) ([]byte, error) { hdr := jws.NewHeaders() - if err := hdr.Set(jws.AlgorithmKey, jwa.ES256); err != nil { + if err := hdr.Set(jws.AlgorithmKey, jwa.ES256()); err != nil { return nil, fmt.Errorf("setting algorithm: %w", err) } if err := hdr.Set(jws.TypeKey, "JWT"); err != nil { @@ -87,7 +88,7 @@ func (f *FakeAuthenticator) SignToken(t jwt.Token) ([]byte, error) { if err := hdr.Set(jws.KeyIDKey, KeyID); err != nil { return nil, fmt.Errorf("setting Key ID: %w", err) } - return jwt.Sign(t, jwa.ES256, f.PrivateKey, jwt.WithHeaders(hdr)) + return jwt.Sign(t, jwt.WithKey(jwa.ES256(), f.PrivateKey, jws.WithProtectedHeaders(hdr))) } // CreateJWSWithClaims is a helper function to create JWT's with the specified diff --git a/examples/authenticated-api/stdhttp/server/jwt_authenticator.go b/examples/authenticated-api/stdhttp/server/jwt_authenticator.go index b29a67302c..163827e24b 100644 --- a/examples/authenticated-api/stdhttp/server/jwt_authenticator.go +++ b/examples/authenticated-api/stdhttp/server/jwt_authenticator.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3filter" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v3/jwt" ) // JWSValidator is used to validate JWS payloads and return a JWT if they're @@ -88,30 +88,27 @@ func Authenticate(v JWSValidator, ctx context.Context, input *openapi3filter.Aut // as a list under the "perms" claim, short for permissions, to keep the token // shorter. func GetClaimsFromToken(t jwt.Token) ([]string, error) { - rawPerms, found := t.Get(PermissionsClaim) - if !found { + if !t.Has(PermissionsClaim) { // If the perms aren't found, it means that the token has none, but it has // passed signature validation by now, so it's a valid token, so we return // the empty list. return make([]string, 0), nil } - // rawPerms will be an untyped JSON list, so we need to convert it to - // a string list. - rawList, ok := rawPerms.([]interface{}) - if !ok { - return nil, fmt.Errorf("'%s' claim is unexpected type'", PermissionsClaim) + var rawList []interface{} + if err := t.Get(PermissionsClaim, &rawList); err != nil { + return nil, fmt.Errorf("getting %q claim: %w", PermissionsClaim, err) } claims := make([]string, len(rawList)) - for i, rawClaim := range rawList { - var ok bool - claims[i], ok = rawClaim.(string) + claim, ok := rawClaim.(string) if !ok { return nil, fmt.Errorf("%s[%d] is not a string", PermissionsClaim, i) } + claims[i] = claim } + return claims, nil } diff --git a/examples/go.mod b/examples/go.mod index 998f23e291..9894cd261e 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -13,7 +13,7 @@ require ( github.com/gorilla/mux v1.8.1 github.com/kataras/iris/v12 v12.2.11 github.com/labstack/echo/v4 v4.15.1 - github.com/lestrrat-go/jwx v1.2.31 + github.com/lestrrat-go/jwx/v3 v3.0.13 github.com/oapi-codegen/echo-middleware v1.0.2 github.com/oapi-codegen/fiber-middleware v1.0.2 github.com/oapi-codegen/gin-middleware v1.0.2 @@ -67,11 +67,12 @@ require ( github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/blackmagic v1.0.4 // indirect + github.com/lestrrat-go/dsig v1.0.0 // indirect + github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.2 // indirect + github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/mailgun/raymond/v2 v2.0.48 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -85,13 +86,13 @@ require ( github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.54.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/closestmatch v2.1.0+incompatible // indirect + github.com/segmentio/asm v1.2.1 // indirect github.com/sirupsen/logrus v1.9.1 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect @@ -101,6 +102,7 @@ require ( github.com/ugorji/go/codec v1.3.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect + github.com/valyala/fastjson v1.6.7 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index 49512be9b8..a30c9a83b6 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -153,19 +153,20 @@ github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0 github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA= +github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= +github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38= +github.com/lestrrat-go/dsig v1.0.0/go.mod h1:dEgoOYYEJvW6XGbLasr8TFcAxoWrKlbQvmJgCR0qkDo= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7gcrVVMFPOzY= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= -github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/httprc/v3 v3.0.2 h1:7u4HUaD0NQbf2/n5+fyp+T10hNCsAnwKfqn4A4Baif0= +github.com/lestrrat-go/httprc/v3 v3.0.2/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= +github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk= +github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU= +github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= +github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= @@ -227,8 +228,6 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0 github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -245,6 +244,8 @@ github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQ github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= +github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -262,7 +263,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -284,6 +284,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= +github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= From c322d1a39424a20b0a07f7e7190c45cede3775db Mon Sep 17 00:00:00 2001 From: TelpeNight Date: Thu, 26 Mar 2026 01:27:31 +0100 Subject: [PATCH 18/62] add tests for https://github.com/oapi-codegen/oapi-codegen/issues/2183 (#2184) * add tests for https://github.com/oapi-codegen/oapi-codegen/issues/2183 * fix(client): preserve literal commas in form/explode=false query params The generated client code was round-tripping styled query parameter fragments through url.ParseQuery + url.Values.Encode(), which re-encoded comma delimiters as %2C. Per the OpenAPI spec, form/explode=false arrays should use literal commas as delimiters (e.g. color=blue,black,brown). Change the client template to collect pre-encoded fragments from StyleParamWithLocation and join them directly, bypassing the re-encoding. Also moves the issue-2183 test to internal/test/issues/issue-2183/, extends it with explode=true and multi-param cases, and documents the remaining server-side limitation (oapi-codegen/runtime#91) for values containing embedded commas. Fixes #2183 Co-Authored-By: Claude Opus 4.6 * Regenerate affected boilerplate * Make sure to URL encode parameter names * Use non-deprecated runtime code * Update runtime and unstub test This exercises all the test cases in the bug. I will do a followup commit to fix all parameter handling. * Defer client parameter styling to runtime The split partial styling between client and runtime causes problems, so just have runtime do all of the work. --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.6 --- examples/generate/serverurls/gen.go | 1 + .../petstore-expanded/petstore-client.gen.go | 31 +++-- internal/test/any_of/param/param.gen.go | 27 ++-- internal/test/go.mod | 2 +- internal/test/go.sum | 4 +- .../issues/issue-2031/prefer/issue2031.gen.go | 19 +-- .../issues/issue-2183/communication_test.go | 116 ++++++++++++++++++ .../name_conflict_resolution.gen.go | 19 +-- internal/test/parameters/parameters.gen.go | 113 ++++++++--------- internal/test/schemas/schemas.gen.go | 19 +-- internal/test/strict-server/stdhttp/go.mod | 2 +- internal/test/strict-server/stdhttp/go.sum | 4 +- pkg/codegen/templates/client.tmpl | 21 ++-- 13 files changed, 250 insertions(+), 128 deletions(-) create mode 100644 internal/test/issues/issue-2183/communication_test.go diff --git a/examples/generate/serverurls/gen.go b/examples/generate/serverurls/gen.go index b32073b2cd..79eace7a7a 100644 --- a/examples/generate/serverurls/gen.go +++ b/examples/generate/serverurls/gen.go @@ -55,6 +55,7 @@ func NewServerUrlTheProductionAPIServer(basePath ServerUrlTheProductionAPIServer u = strings.ReplaceAll(u, "{basePath}", string(basePath)) u = strings.ReplaceAll(u, "{noDefault}", string(noDefault)) + // TODO in the future, this will validate that the value is part of the ServerUrlTheProductionAPIServerPortVariable enum u = strings.ReplaceAll(u, "{port}", string(port)) u = strings.ReplaceAll(u, "{username}", string(username)) diff --git a/examples/petstore-expanded/petstore-client.gen.go b/examples/petstore-expanded/petstore-client.gen.go index 9bd928f497..aa35c93ca6 100644 --- a/examples/petstore-expanded/petstore-client.gen.go +++ b/examples/petstore-expanded/petstore-client.gen.go @@ -226,41 +226,38 @@ func NewFindPetsRequest(server string, params *FindPetsParams) (*http.Request, e } 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.Tags != nil { - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "tags", runtime.ParamLocationQuery, *params.Tags); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + if queryFragments, err := runtime.StyleParamWithLocation("form", true, "tags", runtime.ParamLocationQuery, *params.Tags); err != nil { return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } + rawQueryFragments = append(rawQueryFragments, queryFragments) } } if params.Limit != nil { - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + if queryFragments, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } + rawQueryFragments = append(rawQueryFragments, queryFragments) } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest("GET", queryURL.String(), nil) diff --git a/internal/test/any_of/param/param.gen.go b/internal/test/any_of/param/param.gen.go index 2a082006cc..825bafeefd 100644 --- a/internal/test/any_of/param/param.gen.go +++ b/internal/test/any_of/param/param.gen.go @@ -282,19 +282,21 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, 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.Test != nil { if queryFrag, err := runtime.StyleParamWithOptions("form", true, "test", *params.Test, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -304,19 +306,18 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, err if queryFrag, err := runtime.StyleParamWithOptions("form", true, "test2", *params.Test2, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) diff --git a/internal/test/go.mod b/internal/test/go.mod index 3883c7548e..8f1d5e347a 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -15,7 +15,7 @@ require ( github.com/labstack/echo/v4 v4.15.1 github.com/oapi-codegen/nullable v1.1.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/runtime v1.3.1 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v2 v2.4.0 diff --git a/internal/test/go.sum b/internal/test/go.sum index e4e6e813f1..7153d67001 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -180,8 +180,8 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+5xB9g= +github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= diff --git a/internal/test/issues/issue-2031/prefer/issue2031.gen.go b/internal/test/issues/issue-2031/prefer/issue2031.gen.go index 2aeb2c4b88..2dcb3372d1 100644 --- a/internal/test/issues/issue-2031/prefer/issue2031.gen.go +++ b/internal/test/issues/issue-2031/prefer/issue2031.gen.go @@ -128,25 +128,30 @@ func NewGetTestRequest(server string, params *GetTestParams) (*http.Request, 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.UserIds != nil { if queryFrag, err := runtime.StyleParamWithOptions("form", true, "user_ids[]", params.UserIds, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) diff --git a/internal/test/issues/issue-2183/communication_test.go b/internal/test/issues/issue-2183/communication_test.go new file mode 100644 index 0000000000..68c872eca3 --- /dev/null +++ b/internal/test/issues/issue-2183/communication_test.go @@ -0,0 +1,116 @@ +package issue2183 + +import ( + "reflect" + "strings" + "testing" + + "github.com/oapi-codegen/runtime" +) + +func TestQueryCommunication(t *testing.T) { + + type ParamDefinition struct { + style string + explode bool + paramName string + value any + } + + testCases := []struct { + Name string + // Params defines the query parameters to serialize and deserialize. + Params []ParamDefinition + // SpecQuery is the expected raw query string per the OpenAPI spec. + SpecQuery string + }{ + { + Name: "explode=false", + Params: []ParamDefinition{{ + style: "form", + explode: false, + paramName: "color", + value: []string{"blue", "black", "brown"}, + }}, + // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#style-examples + SpecQuery: "color=blue,black,brown", + }, + { + Name: "explode=false;commas", + Params: []ParamDefinition{{ + style: "form", + explode: false, + paramName: "search_term", + value: []string{"a", "b", "c,d"}, + }}, + SpecQuery: "search_term=a,b,c%2Cd", + }, + { + Name: "explode=true", + Params: []ParamDefinition{{ + style: "form", + explode: true, + paramName: "color", + value: []string{"blue", "black", "brown"}, + }}, + SpecQuery: "color=blue&color=black&color=brown", + }, + { + Name: "multiple params", + Params: []ParamDefinition{ + { + style: "form", + explode: false, + paramName: "color", + value: []string{"blue", "black"}, + }, + { + style: "form", + explode: false, + paramName: "size", + value: []string{"s", "m", "l"}, + }, + }, + SpecQuery: "color=blue,black&size=s,m,l", + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + + // rawQueryFragments collects pre-encoded query fragments from + // styled parameters, matching the generated client pattern. + var rawQueryFragments []string + + for _, param := range tc.Params { + + // following code equivalent to generated client (after fix) + queryFrag, err := runtime.StyleParamWithOptions(param.style, param.explode, param.paramName, param.value, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery}) + if err != nil { + t.Fatal(err) + } + rawQueryFragments = append(rawQueryFragments, queryFrag) + } + + rawQuery := strings.Join(rawQueryFragments, "&") + t.Logf("client query: %s", rawQuery) + if tc.SpecQuery != "" && rawQuery != tc.SpecQuery { + t.Errorf("spec query: expected %q, got %q", tc.SpecQuery, rawQuery) + } + + // following code equivalent to generated server + for _, param := range tc.Params { + + dest := reflect.New(reflect.TypeOf(param.value)) + err := runtime.BindRawQueryParameter(param.style, param.explode, true, param.paramName, rawQuery, dest.Interface()) + if err != nil { + t.Error(err) + } else if !reflect.DeepEqual(dest.Elem().Interface(), param.value) { + t.Errorf("expecting %v, got %v", param.value, dest.Elem().Interface()) + } + + } + + }) + } +} diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go index fa5b29bc16..bc3fb1ba5a 100644 --- a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -1091,25 +1091,30 @@ func NewPostFooRequestWithBody(server string, params *PostFooParams, contentType } 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.Bar != nil { if queryFrag, err := runtime.StyleParamWithOptions("form", true, "bar", *params.Bar, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) diff --git a/internal/test/parameters/parameters.gen.go b/internal/test/parameters/parameters.gen.go index 6b68f2fd25..9a66132841 100644 --- a/internal/test/parameters/parameters.gen.go +++ b/internal/test/parameters/parameters.gen.go @@ -747,25 +747,30 @@ func NewEnumParamsRequest(server string, params *EnumParamsParams) (*http.Reques } 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.EnumPathParam != nil { if queryFrag, err := runtime.StyleParamWithOptions("form", true, "enumPathParam", *params.EnumPathParam, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) @@ -1220,21 +1225,26 @@ func NewGetDeepObjectRequest(server string, params *GetDeepObjectParams) (*http. } 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 queryFrag, err := runtime.StyleParamWithOptions("deepObject", true, "deepObj", params.DeepObj, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) @@ -1265,19 +1275,21 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re } 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.Ea != nil { if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ea", *params.Ea, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1287,13 +1299,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", false, "a", *params.A, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1303,13 +1311,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", true, "eo", *params.Eo, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1319,13 +1323,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", false, "o", *params.O, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1335,13 +1335,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ep", *params.Ep, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1351,13 +1347,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", false, "p", *params.P, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1367,13 +1359,9 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ps", *params.Ps, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } @@ -1393,19 +1381,18 @@ func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Re if queryFrag, err := runtime.StyleParamWithOptions("form", true, "1s", *params.N1s, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index ad4e412d05..fe10c8c7eb 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -661,21 +661,26 @@ func NewIssue9RequestWithBody(server string, params *Issue9Params, contentType s } 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 queryFrag, err := runtime.StyleParamWithOptions("form", true, "foo", params.Foo, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) } } - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } req, err := http.NewRequest(http.MethodGet, queryURL.String(), body) diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 443f10af94..18f7838442 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -10,7 +10,7 @@ require ( github.com/getkin/kin-openapi v0.134.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/oapi-codegen/v2/internal/test v0.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/runtime v1.3.1 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 5ba1c74b30..743c6649a8 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -61,8 +61,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+5xB9g= +github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= diff --git a/pkg/codegen/templates/client.tmpl b/pkg/codegen/templates/client.tmpl index d85ffb5631..74407a3ebf 100644 --- a/pkg/codegen/templates/client.tmpl +++ b/pkg/codegen/templates/client.tmpl @@ -203,7 +203,13 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr {{if .QueryParams}} 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 {{range $paramIdx, $param := .QueryParams}} {{if .RequiresNilCheck}} if params.{{.GoName}} != nil { {{end}} {{if .IsPassThrough}} @@ -220,19 +226,18 @@ func New{{$opid}}Request{{if .HasBody}}WithBody{{end}}(server string{{genParamAr {{if .IsStyled}} if queryFrag, err := runtime.StyleParamWithOptions("{{.Style}}", {{.Explode}}, "{{.ParamName}}", {{if and .RequiresNilCheck .HasOptionalPointer}}*{{end}}params.{{.GoName}}, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}); err != nil { return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } } {{end}} {{if .RequiresNilCheck}}}{{end}} {{end}} - queryURL.RawQuery = queryValues.Encode() + if encoded := queryValues.Encode(); encoded != "" { + rawQueryFragments = append(rawQueryFragments, encoded) + } + queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } {{end}}{{/* if .QueryParams */}} req, err := http.NewRequest({{.Method | httpMethodConstant}}, queryURL.String(), {{if .HasBody}}body{{else}}nil{{end}}) From a3a04d4d994dea6a2f0c6ac1bab02cb2ca6a5d30 Mon Sep 17 00:00:00 2001 From: Joe Petrich Date: Fri, 27 Mar 2026 01:01:44 -0400 Subject: [PATCH 19/62] Support handler-specific middleware for gofiber (#2302) * feat(fiber): add per-handler middleware support (HandlerMiddlewares) (#2) Add Fiber per-handler middleware support * fix(test/issue518): add models:true to config so generated code compiles (#4) * chore(fiber): regenerate existing fiber server files with middleware chain support (#5) --------- Co-authored-by: Courty --- .../issue-1529/strict-fiber/issue1529.gen.go | 26 ++- internal/test/issues/issue1469/main.gen.go | 26 ++- internal/test/issues/issue518/config.yaml | 6 + internal/test/issues/issue518/doc.go | 3 + internal/test/issues/issue518/main.gen.go | 101 +++++++++ internal/test/issues/issue518/main_test.go | 88 ++++++++ internal/test/issues/issue518/spec.yaml | 21 ++ .../test/strict-server/fiber/server.gen.go | 208 ++++++++++++++++-- .../templates/fiber/fiber-handler.tmpl | 2 + .../templates/fiber/fiber-middleware.tmpl | 18 +- 10 files changed, 469 insertions(+), 30 deletions(-) create mode 100644 internal/test/issues/issue518/config.yaml create mode 100644 internal/test/issues/issue518/doc.go create mode 100644 internal/test/issues/issue518/main.gen.go create mode 100644 internal/test/issues/issue518/main_test.go create mode 100644 internal/test/issues/issue518/spec.yaml diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index f4fe591c04..62cd9ce025 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -268,21 +268,36 @@ type ServerInterface interface { // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { - Handler ServerInterface + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error // Test operation middleware func (siw *ServerInterfaceWrapper) Test(c *fiber.Ctx) error { - return siw.Handler.Test(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.Test(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FiberServerOptions provides options for the Fiber server. type FiberServerOptions struct { - BaseURL string - Middlewares []MiddlewareFunc + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -293,7 +308,8 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { wrapper := ServerInterfaceWrapper{ - Handler: si, + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/internal/test/issues/issue1469/main.gen.go b/internal/test/issues/issue1469/main.gen.go index 11f87b0c4f..4a1161368c 100644 --- a/internal/test/issues/issue1469/main.gen.go +++ b/internal/test/issues/issue1469/main.gen.go @@ -16,21 +16,36 @@ type ServerInterface interface { // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { - Handler ServerInterface + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error // Test operation middleware func (siw *ServerInterfaceWrapper) Test(c *fiber.Ctx) error { - return siw.Handler.Test(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.Test(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FiberServerOptions provides options for the Fiber server. type FiberServerOptions struct { - BaseURL string - Middlewares []MiddlewareFunc + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -41,7 +56,8 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { wrapper := ServerInterfaceWrapper{ - Handler: si, + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/internal/test/issues/issue518/config.yaml b/internal/test/issues/issue518/config.yaml new file mode 100644 index 0000000000..8fca51fa54 --- /dev/null +++ b/internal/test/issues/issue518/config.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: issue518 +generate: + fiber-server: true + models: true +output: main.gen.go diff --git a/internal/test/issues/issue518/doc.go b/internal/test/issues/issue518/doc.go new file mode 100644 index 0000000000..5276da3dd7 --- /dev/null +++ b/internal/test/issues/issue518/doc.go @@ -0,0 +1,3 @@ +package issue518 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue518/main.gen.go b/internal/test/issues/issue518/main.gen.go new file mode 100644 index 0000000000..a7b64d5808 --- /dev/null +++ b/internal/test/issues/issue518/main.gen.go @@ -0,0 +1,101 @@ +// Package issue518 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 issue518 + +import ( + "github.com/gofiber/fiber/v2" +) + +const ( + BearerAuthScopes bearerAuthContextKey = "bearerAuth.Scopes" +) + +// bearerAuthContextKey is the context key for bearerAuth security scheme +type bearerAuthContextKey string + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /auth-check) + AuthCheck(c *fiber.Ctx) error + + // (GET /test) + Test(c *fiber.Ctx) error +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc +} + +type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error + +// AuthCheck operation middleware +func (siw *ServerInterfaceWrapper) AuthCheck(c *fiber.Ctx) error { + + c.Context().SetUserValue((BearerAuthScopes), []string{}) + + handler := func(c *fiber.Ctx) error { + return siw.Handler.AuthCheck(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// Test operation middleware +func (siw *ServerInterfaceWrapper) Test(c *fiber.Ctx) error { + + handler := func(c *fiber.Ctx) error { + return siw.Handler.Test(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// FiberServerOptions provides options for the Fiber server. +type FiberServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router fiber.Router, si ServerInterface) { + RegisterHandlersWithOptions(router, si, FiberServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, + } + + for _, m := range options.Middlewares { + router.Use(fiber.Handler(m)) + } + + router.Get(options.BaseURL+"/auth-check", wrapper.AuthCheck) + + router.Get(options.BaseURL+"/test", wrapper.Test) + +} diff --git a/internal/test/issues/issue518/main_test.go b/internal/test/issues/issue518/main_test.go new file mode 100644 index 0000000000..f1d7471c1b --- /dev/null +++ b/internal/test/issues/issue518/main_test.go @@ -0,0 +1,88 @@ +package issue518 + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/gofiber/fiber/v2" + "github.com/stretchr/testify/assert" +) + +type impl struct{} + +// (GET /auth-check) +func (i *impl) AuthCheck(c *fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) +} + +// (GET /test) +func (i *impl) Test(c *fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) +} + +// hasSecurityScopes returns true if the BearerAuthScopes key was set in context, +// even if the scopes slice is empty (an empty slice means the security scheme is +// defined on the operation with no required scopes, which still requires auth). +func hasSecurityScopes(c *fiber.Ctx) bool { + _, ok := c.Context().UserValue(BearerAuthScopes).([]string) + return ok +} + +func TestIssue518(t *testing.T) { + server := &impl{} + + assert.NotPanics(t, func() { + r := fiber.New() + RegisterHandlers(r, server) + }) + + assert.NotPanics(t, func() { + r := fiber.New() + RegisterHandlersWithOptions(r, server, FiberServerOptions{ + Middlewares: []MiddlewareFunc{ + func(c *fiber.Ctx) error { + return nil + }, + }, + HandlerMiddlewares: []HandlerMiddlewareFunc{ + func(c *fiber.Ctx, next fiber.Handler) error { + if hasSecurityScopes(c) && c.Get(fiber.HeaderAuthorization) == "" { + return c.SendStatus(fiber.StatusUnauthorized) + } + return next(c) + }, + }, + }) + }) + + t.Run("secured endpoint requires auth when scopes are present", func(t *testing.T) { + r := fiber.New() + RegisterHandlersWithOptions(r, server, FiberServerOptions{ + HandlerMiddlewares: []HandlerMiddlewareFunc{ + func(c *fiber.Ctx, next fiber.Handler) error { + if hasSecurityScopes(c) && c.Get(fiber.HeaderAuthorization) == "" { + return c.SendStatus(fiber.StatusUnauthorized) + } + return next(c) + }, + }, + }) + + req := httptest.NewRequest(http.MethodGet, "/auth-check", nil) + resp, err := r.Test(req) + assert.NoError(t, err) + assert.Equal(t, fiber.StatusUnauthorized, resp.StatusCode) + + req = httptest.NewRequest(http.MethodGet, "/auth-check", nil) + req.Header.Set(fiber.HeaderAuthorization, "Bearer token") + resp, err = r.Test(req) + assert.NoError(t, err) + assert.Equal(t, fiber.StatusOK, resp.StatusCode) + + req = httptest.NewRequest(http.MethodGet, "/test", nil) + resp, err = r.Test(req) + assert.NoError(t, err) + assert.Equal(t, fiber.StatusOK, resp.StatusCode) + }) +} diff --git a/internal/test/issues/issue518/spec.yaml b/internal/test/issues/issue518/spec.yaml new file mode 100644 index 0000000000..da011a7eee --- /dev/null +++ b/internal/test/issues/issue518/spec.yaml @@ -0,0 +1,21 @@ +openapi: "3.0.1" +components: + securitySchemes: + bearerAuth: + scheme: bearer + type: http +paths: + /auth-check: + get: + operationId: authCheck + security: + - bearerAuth: [] + responses: + 200: + description: good + /test: + get: + operationId: test + responses: + 200: + description: good diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index 44d3c65de7..2ab5fc04b9 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -72,45 +72,119 @@ type ServerInterface interface { // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { - Handler ServerInterface + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error // JSONExample operation middleware func (siw *ServerInterfaceWrapper) JSONExample(c *fiber.Ctx) error { - return siw.Handler.JSONExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.JSONExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // MultipartExample operation middleware func (siw *ServerInterfaceWrapper) MultipartExample(c *fiber.Ctx) error { - return siw.Handler.MultipartExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.MultipartExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // MultipartRelatedExample operation middleware func (siw *ServerInterfaceWrapper) MultipartRelatedExample(c *fiber.Ctx) error { - return siw.Handler.MultipartRelatedExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.MultipartRelatedExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // MultipleRequestAndResponseTypes operation middleware func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(c *fiber.Ctx) error { - return siw.Handler.MultipleRequestAndResponseTypes(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.MultipleRequestAndResponseTypes(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(c *fiber.Ctx) error { - return siw.Handler.RequiredJSONBody(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.RequiredJSONBody(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // RequiredTextBody operation middleware func (siw *ServerInterfaceWrapper) RequiredTextBody(c *fiber.Ctx) error { - return siw.Handler.RequiredTextBody(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.RequiredTextBody(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // ReservedGoKeywordParameters operation middleware @@ -126,37 +200,109 @@ func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(c *fiber.Ctx) err return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter type: %w", err).Error()) } - return siw.Handler.ReservedGoKeywordParameters(c, pType) + handler := func(c *fiber.Ctx) error { + return siw.Handler.ReservedGoKeywordParameters(c, pType) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // ReusableResponses operation middleware func (siw *ServerInterfaceWrapper) ReusableResponses(c *fiber.Ctx) error { - return siw.Handler.ReusableResponses(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.ReusableResponses(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // TextExample operation middleware func (siw *ServerInterfaceWrapper) TextExample(c *fiber.Ctx) error { - return siw.Handler.TextExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.TextExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // UnknownExample operation middleware func (siw *ServerInterfaceWrapper) UnknownExample(c *fiber.Ctx) error { - return siw.Handler.UnknownExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.UnknownExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // UnspecifiedContentType operation middleware func (siw *ServerInterfaceWrapper) UnspecifiedContentType(c *fiber.Ctx) error { - return siw.Handler.UnspecifiedContentType(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.UnspecifiedContentType(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // URLEncodedExample operation middleware func (siw *ServerInterfaceWrapper) URLEncodedExample(c *fiber.Ctx) error { - return siw.Handler.URLEncodedExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.URLEncodedExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // HeadersExample operation middleware @@ -206,19 +352,44 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *fiber.Ctx) error { } - return siw.Handler.HeadersExample(c, params) + handler := func(c *fiber.Ctx) error { + return siw.Handler.HeadersExample(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // UnionExample operation middleware func (siw *ServerInterfaceWrapper) UnionExample(c *fiber.Ctx) error { - return siw.Handler.UnionExample(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.UnionExample(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FiberServerOptions provides options for the Fiber server. type FiberServerOptions struct { - BaseURL string - Middlewares []MiddlewareFunc + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -229,7 +400,8 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { wrapper := ServerInterfaceWrapper{ - Handler: si, + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/pkg/codegen/templates/fiber/fiber-handler.tmpl b/pkg/codegen/templates/fiber/fiber-handler.tmpl index 7745e0d88e..46aab9607d 100644 --- a/pkg/codegen/templates/fiber/fiber-handler.tmpl +++ b/pkg/codegen/templates/fiber/fiber-handler.tmpl @@ -2,6 +2,7 @@ type FiberServerOptions struct { BaseURL string Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -13,6 +14,7 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { {{if .}}wrapper := ServerInterfaceWrapper{ Handler: si, +HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index dc48266696..5fcbe41383 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -1,9 +1,11 @@ // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error {{range .}}{{$opid := .OperationId}} @@ -36,7 +38,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{end}} {{range .SecurityDefinitions}} - c.Context().SetUserValue(({{.ProviderName | ucFirst}}Scopes), {{toStringArray .Scopes}}) + c.Context().SetUserValue(({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} {{if .RequiresParamObject}} @@ -168,6 +170,18 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{end}} {{end}} - return siw.Handler.{{.OperationId}}(c{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) + handler := func(c *fiber.Ctx) error { + return siw.Handler.{{.OperationId}}(c{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } {{end}} From e126f5a4d8015eecb3dda96d517ce2b243dc9921 Mon Sep 17 00:00:00 2001 From: Nicolas Mattelaer <113113091+nicolasmattelaer@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:33:12 +0200 Subject: [PATCH 20/62] change FormParams to FormValues (#2311) Co-authored-by: nmattela --- pkg/codegen/templates/strict/strict-echo5.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/codegen/templates/strict/strict-echo5.tmpl b/pkg/codegen/templates/strict/strict-echo5.tmpl index 1f377bfdab..5afb443606 100644 --- a/pkg/codegen/templates/strict/strict-echo5.tmpl +++ b/pkg/codegen/templates/strict/strict-echo5.tmpl @@ -38,7 +38,7 @@ type strictHandler struct { } request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = &body {{else if eq .NameTag "Formdata" -}} - if form, err := ctx.FormParams(); err == nil { + if form, err := ctx.FormValues(); err == nil { var body {{$opid}}{{.NameTag}}RequestBody if err := runtime.BindForm(&body, form, nil, nil); err != nil { return err From 8822002562cd177574eeac49d084ba91dd37fea8 Mon Sep 17 00:00:00 2001 From: Gaiaz Iusipov Date: Fri, 3 Apr 2026 08:42:22 +0800 Subject: [PATCH 21/62] style: simplify and modernize (#2305) * style: simplify and modernize Signed-off-by: Gaiaz Iusipov * revert: adding compile-time checks Signed-off-by: Gaiaz Iusipov --------- Signed-off-by: Gaiaz Iusipov Co-authored-by: Marcin Romaszewicz --- .../authenticated-api/stdhttp/api/api.gen.go | 4 +- .../minimal-server/stdhttp/api/ping.gen.go | 4 +- .../stdhttp/api/petstore.gen.go | 4 +- .../test/issues/issue-1963/issue1963.gen.go | 4 +- .../test/issues/issue-2190/issue2190.gen.go | 4 +- .../test/issues/issue-2232/issue2232.gen.go | 4 +- .../test/strict-server/stdhttp/server.gen.go | 4 +- pkg/codegen/codegen.go | 43 +++++++--------- pkg/codegen/gather.go | 43 +++++++++------- pkg/codegen/merge_schemas.go | 25 ++++----- pkg/codegen/merge_schemas_v1.go | 3 +- pkg/codegen/operations.go | 51 ++++++++----------- pkg/codegen/prune.go | 22 ++++---- pkg/codegen/resolve_names.go | 4 +- pkg/codegen/schema.go | 10 ++-- pkg/codegen/template_helpers.go | 10 ++-- .../templates/stdhttp/std-http-handler.tmpl | 4 +- pkg/codegen/typemapping.go | 18 +++---- pkg/codegen/utils.go | 46 +++++------------ 19 files changed, 136 insertions(+), 171 deletions(-) diff --git a/examples/authenticated-api/stdhttp/api/api.gen.go b/examples/authenticated-api/stdhttp/api/api.gen.go index da76ee17b2..b370659441 100644 --- a/examples/authenticated-api/stdhttp/api/api.gen.go +++ b/examples/authenticated-api/stdhttp/api/api.gen.go @@ -543,10 +543,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/examples/minimal-server/stdhttp/api/ping.gen.go b/examples/minimal-server/stdhttp/api/ping.gen.go index 0b1984332e..0d4ab7751a 100644 --- a/examples/minimal-server/stdhttp/api/ping.gen.go +++ b/examples/minimal-server/stdhttp/api/ping.gen.go @@ -119,10 +119,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/examples/petstore-expanded/stdhttp/api/petstore.gen.go b/examples/petstore-expanded/stdhttp/api/petstore.gen.go index 1581d7705f..74019839df 100644 --- a/examples/petstore-expanded/stdhttp/api/petstore.gen.go +++ b/examples/petstore-expanded/stdhttp/api/petstore.gen.go @@ -259,10 +259,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/internal/test/issues/issue-1963/issue1963.gen.go b/internal/test/issues/issue-1963/issue1963.gen.go index 9c5b00bd9b..15164e4b62 100644 --- a/internal/test/issues/issue-1963/issue1963.gen.go +++ b/internal/test/issues/issue-1963/issue1963.gen.go @@ -220,10 +220,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/internal/test/issues/issue-2190/issue2190.gen.go b/internal/test/issues/issue-2190/issue2190.gen.go index d911a8474c..8cc8570388 100644 --- a/internal/test/issues/issue-2190/issue2190.gen.go +++ b/internal/test/issues/issue-2190/issue2190.gen.go @@ -345,10 +345,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/internal/test/issues/issue-2232/issue2232.gen.go b/internal/test/issues/issue-2232/issue2232.gen.go index 9b98648470..b99598ba4f 100644 --- a/internal/test/issues/issue-2232/issue2232.gen.go +++ b/internal/test/issues/issue-2232/issue2232.gen.go @@ -208,10 +208,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 271fcdccd4..8eca306a54 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -411,10 +411,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 44cfc6faf2..2d0ed9a0c1 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -24,9 +24,11 @@ import ( "go/scanner" "io" "io/fs" + "maps" "net/http" "os" "runtime/debug" + "slices" "sort" "strings" "text/template" @@ -103,11 +105,8 @@ func constructImportMapping(importMapping map[string]string) importMap { ) { - var packagePaths []string - for _, packageName := range importMapping { - packagePaths = append(packagePaths, packageName) - } - sort.Strings(packagePaths) + packagePaths := slices.Collect(maps.Values(importMapping)) + slices.Sort(packagePaths) for _, packagePath := range packagePaths { if _, ok := pathToImport[packagePath]; !ok && packagePath != importMappingCurrentPackage { @@ -255,7 +254,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { if err != nil { return "", fmt.Errorf("error getting type definition imports: %w", err) } - MergeImports(xGoTypeImports, imprts) + maps.Copy(xGoTypeImports, imprts) } var serverURLsDefinitions string @@ -626,11 +625,7 @@ func GenerateConstants(t *template.Template, ops []OperationDefinition) (string, } } - var providerNames []string - for providerName := range providerNameMap { - providerNames = append(providerNames, providerName) - } - + providerNames := slices.Collect(maps.Keys(providerNameMap)) sort.Strings(providerNames) constants.SecuritySchemeProviderNames = append(constants.SecuritySchemeProviderNames, providerNames...) @@ -944,7 +939,7 @@ func resolvedNameForComponent(section, name string, contentType ...string) strin } if len(matches) > 0 { if len(matches) > 1 { - sort.Strings(matches) + slices.Sort(matches) } return globalState.resolvedNames[matches[0]] } @@ -1243,14 +1238,14 @@ func OperationSchemaImports(s *Schema) (map[string]goImport, error) { if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } imprts, err := GoSchemaImports(&openapi3.SchemaRef{Value: s.OAPISchema}) if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) return res, nil } @@ -1263,7 +1258,7 @@ func OperationImports(ops []OperationDefinition) (map[string]goImport, error) { if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } @@ -1272,7 +1267,7 @@ func OperationImports(ops []OperationDefinition) (map[string]goImport, error) { if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } for _, b := range op.Responses { @@ -1281,7 +1276,7 @@ func OperationImports(ops []OperationDefinition) (map[string]goImport, error) { if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } @@ -1316,7 +1311,7 @@ func GetTypeDefinitionsImports(swagger *openapi3.T, excludeSchemas []string) (ma } for _, imprts := range []map[string]goImport{schemaImports, reqBodiesImports, responsesImports, parametersImports} { - MergeImports(res, imprts) + maps.Copy(res, imprts) } return res, nil } @@ -1343,14 +1338,14 @@ func GoSchemaImports(schemas ...*openapi3.SchemaRef) (map[string]goImport, error if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } else if t.Is("array") { imprts, err := GoSchemaImports(schemaVal.Items) if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } return res, nil @@ -1371,7 +1366,7 @@ func GetSchemaImports(schemas map[string]*openapi3.SchemaRef, excludeSchemas []s if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } return res, nil } @@ -1389,7 +1384,7 @@ func GetRequestBodiesImports(bodies map[string]*openapi3.RequestBodyRef) (map[st if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } return res, nil @@ -1408,7 +1403,7 @@ func GetResponsesImports(responses map[string]*openapi3.ResponseRef) (map[string if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } } return res, nil @@ -1424,7 +1419,7 @@ func GetParametersImports(params map[string]*openapi3.ParameterRef) (map[string] if err != nil { return nil, err } - MergeImports(res, imprts) + maps.Copy(res, imprts) } return res, nil } diff --git a/pkg/codegen/gather.go b/pkg/codegen/gather.go index 84bd7e55df..0daf2ccf74 100644 --- a/pkg/codegen/gather.go +++ b/pkg/codegen/gather.go @@ -1,14 +1,18 @@ package codegen import ( + "cmp" "fmt" - "sort" + "slices" "strings" "github.com/getkin/kin-openapi/openapi3" + "github.com/oapi-codegen/oapi-codegen/v2/pkg/util" ) +var _ fmt.Stringer = (*SchemaPath)(nil) + // SchemaPath represents the document location of a schema, e.g. // ["components", "schemas", "Pet", "properties", "name"]. type SchemaPath []string @@ -18,6 +22,8 @@ func (sp SchemaPath) String() string { return strings.Join(sp, "/") } +var _ fmt.Stringer = (*SchemaContext)(nil) + // SchemaContext identifies where in the OpenAPI document a schema was found. type SchemaContext int @@ -82,13 +88,13 @@ func (sc SchemaContext) Suffix() string { // GatheredSchema represents a schema discovered during the gather pass, // along with its document location and context metadata. type GatheredSchema struct { - Path SchemaPath - Context SchemaContext - Ref string // $ref string if this is a reference - Schema *openapi3.Schema // The resolved schema value - OperationID string // Enclosing operation's ID, if any - ContentType string // Media type, if from request/response body - StatusCode string // HTTP status code, if from a response + Path SchemaPath + Context SchemaContext + Ref string // $ref string if this is a reference + Schema *openapi3.Schema // The resolved schema value + OperationID string // Enclosing operation's ID, if any + ContentType string // Media type, if from request/response body + StatusCode string // HTTP status code, if from a response ParamIndex int // Parameter index within an operation ComponentName string // The component name (e.g., "Bar" for components/schemas/Bar) GoNameOverride string // x-go-name override from the component or its parent container @@ -105,11 +111,13 @@ func GatherSchemas(spec *openapi3.T, opts Configuration) []*GatheredSchema { var schemas []*GatheredSchema if spec.Components != nil { - schemas = append(schemas, gatherComponentSchemas(spec.Components)...) - schemas = append(schemas, gatherComponentParameters(spec.Components)...) - schemas = append(schemas, gatherComponentResponses(spec.Components)...) - schemas = append(schemas, gatherComponentRequestBodies(spec.Components)...) - schemas = append(schemas, gatherComponentHeaders(spec.Components)...) + schemas = slices.Concat( + gatherComponentSchemas(spec.Components), + gatherComponentParameters(spec.Components), + gatherComponentResponses(spec.Components), + gatherComponentRequestBodies(spec.Components), + gatherComponentHeaders(spec.Components), + ) } // Gather client response wrapper types for operations that will generate @@ -268,10 +276,8 @@ func gatherComponentHeaders(components *openapi3.Components) []*GatheredSchema { // `Response`. These don't correspond to a real schema in the // spec but they need names that don't collide with real types. func gatherClientResponseWrappers(spec *openapi3.T) []*GatheredSchema { - var result []*GatheredSchema - if spec.Paths == nil { - return result + return nil } // Collect all operations sorted for determinism @@ -296,10 +302,11 @@ func gatherClientResponseWrappers(spec *openapi3.T) []*GatheredSchema { } // Sort by operationID for determinism - sort.Slice(ops, func(i, j int) bool { - return ops[i].op.OperationID < ops[j].op.OperationID + slices.SortFunc(ops, func(a, b opEntry) int { + return cmp.Compare(a.op.OperationID, b.op.OperationID) }) + result := make([]*GatheredSchema, 0, len(ops)) for _, entry := range ops { result = append(result, &GatheredSchema{ Path: SchemaPath{"paths", entry.path, entry.method, "x-client-response-wrapper"}, diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index a2c979aa19..b9286703b3 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -3,6 +3,7 @@ package codegen import ( "errors" "fmt" + "maps" "strings" "github.com/getkin/kin-openapi/openapi3" @@ -87,14 +88,10 @@ func mergeAllOf(allOf []*openapi3.SchemaRef) (openapi3.Schema, error) { func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, error) { var result openapi3.Schema - result.Extensions = make(map[string]any) - for k, v := range s1.Extensions { - result.Extensions[k] = v - } - for k, v := range s2.Extensions { - // TODO: Check for collisions - result.Extensions[k] = v - } + result.Extensions = make(map[string]any, len(s1.Extensions)+len(s2.Extensions)) + maps.Copy(result.Extensions, s1.Extensions) + // TODO: Check for collisions + maps.Copy(result.Extensions, s2.Extensions) result.OneOf = append(s1.OneOf, s2.OneOf...) @@ -195,14 +192,10 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, e result.Required = append(s1.Required, s2.Required...) // We merge all properties - result.Properties = make(map[string]*openapi3.SchemaRef) - for k, v := range s1.Properties { - result.Properties[k] = v - } - for k, v := range s2.Properties { - // TODO: detect conflicts - result.Properties[k] = v - } + result.Properties = make(map[string]*openapi3.SchemaRef, len(s1.Properties)+len(s2.Properties)) + maps.Copy(result.Properties, s1.Properties) + // TODO: detect conflicts + maps.Copy(result.Properties, s2.Properties) if isAdditionalPropertiesExplicitFalse(&s1) || isAdditionalPropertiesExplicitFalse(&s2) { result.WithoutAdditionalProperties() diff --git a/pkg/codegen/merge_schemas_v1.go b/pkg/codegen/merge_schemas_v1.go index af83582381..b82eb3e622 100644 --- a/pkg/codegen/merge_schemas_v1.go +++ b/pkg/codegen/merge_schemas_v1.go @@ -3,6 +3,7 @@ package codegen import ( "errors" "fmt" + "slices" "strings" "github.com/getkin/kin-openapi/openapi3" @@ -100,7 +101,7 @@ func GenStructFromAllOf(allOf []*openapi3.SchemaRef, path []string) (string, err } additionalPropertiesPart := fmt.Sprintf("AdditionalProperties map[string]%s `json:\"-\"`", addPropsType) - if !StringInArray(additionalPropertiesPart, objectParts) { + if !slices.Contains(objectParts, additionalPropertiesPart) { objectParts = append(objectParts, additionalPropertiesPart) } } diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index beffe95751..436c46d178 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -16,8 +16,10 @@ package codegen import ( "bufio" "bytes" + "cmp" "fmt" - "sort" + "maps" + "slices" "strconv" "strings" "text/template" @@ -180,7 +182,7 @@ func (pd ParameterDefinition) IndirectOptional() bool { // HasOptionalPointer indicates whether the generated property has an optional pointer associated with it. // This takes into account the `x-go-type-skip-optional-pointer` extension, allowing a parameter definition to control whether the pointer should be skipped. func (pd ParameterDefinition) HasOptionalPointer() bool { - return pd.Required == false && pd.Schema.SkipOptionalPointer == false //nolint:staticcheck + return !pd.Required && !pd.Schema.SkipOptionalPointer } type ParameterDefinitions []ParameterDefinition @@ -198,7 +200,7 @@ func (p ParameterDefinitions) FindByName(name string) *ParameterDefinition { // descriptors into a flat list. This makes it a lot easier to traverse the // data in the template engine. func DescribeParameters(params openapi3.Parameters, path []string) ([]ParameterDefinition, error) { - outParams := make([]ParameterDefinition, 0) + outParams := make([]ParameterDefinition, 0, len(params)) for _, paramOrRef := range params { param := paramOrRef.Value @@ -373,21 +375,21 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini switch { // HAL+JSON: - case StringInArray(contentTypeName, contentTypesHalJSON): + case slices.Contains(contentTypesHalJSON, contentTypeName): typeName = fmt.Sprintf("HALJSON%s", nameNormalizer(responseName)) case contentTypeName == "application/json": // if it's the standard application/json typeName = fmt.Sprintf("JSON%s", nameNormalizer(responseName)) // Vendored JSON - case StringInArray(contentTypeName, contentTypesJSON) || util.IsMediaTypeJson(contentTypeName): + case slices.Contains(contentTypesJSON, contentTypeName) || util.IsMediaTypeJson(contentTypeName): baseTypeName := fmt.Sprintf("%s%s", nameNormalizer(contentTypeName), nameNormalizer(responseName)) typeName = strings.ReplaceAll(baseTypeName, "Json", "JSON") // YAML: - case StringInArray(contentTypeName, contentTypesYAML): + case slices.Contains(contentTypesYAML, contentTypeName): typeName = fmt.Sprintf("YAML%s", nameNormalizer(responseName)) // XML: - case StringInArray(contentTypeName, contentTypesXML): + case slices.Contains(contentTypesXML, contentTypeName): typeName = fmt.Sprintf("XML%s", nameNormalizer(responseName)) default: continue @@ -424,13 +426,10 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini return tds, nil } -func (o OperationDefinition) HasMaskedRequestContentTypes() bool { - for _, body := range o.Bodies { - if !body.IsFixedContentType() { - return true - } - } - return false +func (o *OperationDefinition) HasMaskedRequestContentTypes() bool { + return slices.ContainsFunc(o.Bodies, func(body RequestBodyDefinition) bool { + return !body.IsFixedContentType() + }) } // RequestBodyDefinition describes a request body @@ -730,23 +729,21 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { } func generateDefaultOperationID(opName string, requestPath string) (string, error) { - var operationId = strings.ToLower(opName) - if opName == "" { return "", fmt.Errorf("operation name cannot be an empty string") } - if requestPath == "" { return "", fmt.Errorf("request path cannot be an empty string") } - for _, part := range strings.Split(requestPath, "/") { + operationID := strings.ToLower(opName) + for part := range strings.SplitSeq(requestPath, "/") { if part != "" { - operationId = operationId + "-" + part + operationID = operationID + "-" + part } } - return nameNormalizer(operationId), nil + return nameNormalizer(operationID), nil } // GenerateBodyDefinitions turns the Swagger body definitions into a list of our body @@ -835,7 +832,7 @@ func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBody } if len(content.Encoding) != 0 { - bd.Encoding = make(map[string]RequestBodyEncoding) + bd.Encoding = make(map[string]RequestBodyEncoding, len(content.Encoding)) for k, v := range content.Encoding { encoding := RequestBodyEncoding{ContentType: v.ContentType, Style: v.Style, Explode: v.Explode} bd.Encoding[k] = encoding @@ -844,8 +841,8 @@ func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBody bodyDefinitions = append(bodyDefinitions, bd) } - sort.Slice(bodyDefinitions, func(i, j int) bool { - return bodyDefinitions[i].ContentType < bodyDefinitions[j].ContentType + slices.SortFunc(bodyDefinitions, func(a, b RequestBodyDefinition) int { + return cmp.Compare(a.ContentType, b.ContentType) }) return bodyDefinitions, typeDefinitions, nil } @@ -991,13 +988,9 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition { // Parameter-level extensions take precedence over schema-level ones. extensions := make(map[string]any) if param.Spec.Schema != nil && param.Spec.Schema.Value != nil { - for k, v := range param.Spec.Schema.Value.Extensions { - extensions[k] = v - } - } - for k, v := range param.Spec.Extensions { - extensions[k] = v + maps.Copy(extensions, param.Spec.Schema.Value.Extensions) } + maps.Copy(extensions, param.Spec.Extensions) prop := Property{ Description: param.Spec.Description, JsonFieldName: param.ParamName, diff --git a/pkg/codegen/prune.go b/pkg/codegen/prune.go index e97ba3469e..efdac65f0b 100644 --- a/pkg/codegen/prune.go +++ b/pkg/codegen/prune.go @@ -7,10 +7,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" ) -func stringInSlice(a string, list []string) bool { - return slices.Contains(list, a) -} - type RefWrapper struct { Ref string HasValue bool @@ -398,7 +394,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Schemas { ref := fmt.Sprintf("#/components/schemas/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Schemas, key) } @@ -406,7 +402,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Parameters { ref := fmt.Sprintf("#/components/parameters/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Parameters, key) } @@ -417,7 +413,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { // for key, _ := range swagger.Components.SecuritySchemes { // ref := fmt.Sprintf("#/components/securitySchemes/%s", key) - // if !stringInSlice(ref, refs) { + // if !slices.Contains(refs, ref) { // countRemoved++ // delete(swagger.Components.SecuritySchemes, key) // } @@ -425,7 +421,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.RequestBodies { ref := fmt.Sprintf("#/components/requestBodies/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.RequestBodies, key) } @@ -433,7 +429,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Responses { ref := fmt.Sprintf("#/components/responses/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Responses, key) } @@ -441,7 +437,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Headers { ref := fmt.Sprintf("#/components/headers/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Headers, key) } @@ -449,7 +445,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Examples { ref := fmt.Sprintf("#/components/examples/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Examples, key) } @@ -457,7 +453,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Links { ref := fmt.Sprintf("#/components/links/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Links, key) } @@ -465,7 +461,7 @@ func removeOrphanedComponents(swagger *openapi3.T, refs []string) int { for key := range swagger.Components.Callbacks { ref := fmt.Sprintf("#/components/callbacks/%s", key) - if !stringInSlice(ref, refs) { + if !slices.Contains(refs, ref) { countRemoved++ delete(swagger.Components.Callbacks, key) } diff --git a/pkg/codegen/resolve_names.go b/pkg/codegen/resolve_names.go index f6d65f5b92..1695d67f35 100644 --- a/pkg/codegen/resolve_names.go +++ b/pkg/codegen/resolve_names.go @@ -113,7 +113,7 @@ func resolveCollisions(names []*ResolvedName) { const maxIterations = 20 for _, strategy := range strategies { - for iter := 0; iter < maxIterations; iter++ { + for range maxIterations { groups := groupByName(names) anyCollision := false anyProgress := false @@ -261,7 +261,7 @@ func tryStatusCodeSuffix(group []*ResolvedName) bool { // Returns true if any name was modified, false if no progress was made. func tryParamIndexSuffix(group []*ResolvedName) bool { hasMultipleParams := false - for i := 0; i < len(group); i++ { + for i := range group { for j := i + 1; j < len(group); j++ { if group[i].Schema.ParamIndex != group[j].Schema.ParamIndex { hasMultipleParams = true diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 799e327dea..167b6c627a 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -3,6 +3,7 @@ package codegen import ( "errors" "fmt" + "slices" "strings" "github.com/getkin/kin-openapi/openapi3" @@ -39,7 +40,6 @@ type Schema struct { // The original OpenAPIv3 Schema. OAPISchema *openapi3.Schema - } // IsPrimitive returns true if the schema represents a primitive OpenAPI type @@ -149,7 +149,7 @@ func (p Property) RequiresNilCheck() bool { // HasOptionalPointer indicates whether the generated property has an optional pointer associated with it. // This takes into account the `x-go-type-skip-optional-pointer` extension, allowing a parameter definition to control whether the pointer should be skipped. func (p Property) HasOptionalPointer() bool { - return p.Required == false && p.Schema.SkipOptionalPointer == false //nolint:staticcheck + return !p.Required && !p.Schema.SkipOptionalPointer } // ZeroValueIsNil is a helper function to determine if the given Go type used for this property @@ -269,7 +269,7 @@ func (u UnionElement) String() string { // Method generate union method name for template functions `As/From/Merge`. func (u UnionElement) Method() string { var method strings.Builder - for _, part := range strings.Split(string(u), `.`) { + for part := range strings.SplitSeq(string(u), `.`) { method.WriteString(UppercaseFirstCharacter(part)) } return method.String() @@ -440,7 +440,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { return Schema{}, fmt.Errorf("error generating Go schema for property '%s': %w", pName, err) } - required := StringInArray(pName, schema.Required) + required := slices.Contains(schema.Required, pName) if (pSchema.HasAdditionalProperties || len(pSchema.UnionElements) != 0) && pSchema.RefType == "" { // If we have fields present which have additional properties or union values, @@ -631,7 +631,7 @@ func oapiSchemaToGoType(schema *openapi3.Schema, path []string, outSchema *Schem outSchema.AdditionalTypes = arrayType.AdditionalTypes outSchema.Properties = arrayType.Properties outSchema.DefineViaAlias = true - if sliceContains(globalState.options.OutputOptions.DisableTypeAliasesForType, "array") { + if slices.Contains(globalState.options.OutputOptions.DisableTypeAliasesForType, "array") { outSchema.DefineViaAlias = false } setSkipOptionalPointerForContainerType(outSchema) diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 819c5c5158..3ea88718bb 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -17,6 +17,7 @@ import ( "bytes" "fmt" "os" + "slices" "strings" "text/template" @@ -24,6 +25,7 @@ import ( "golang.org/x/text/language" "github.com/getkin/kin-openapi/openapi3" + "github.com/oapi-codegen/oapi-codegen/v2/pkg/util" ) @@ -147,7 +149,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { SortedMapKeys := SortedMapKeys(responseRef.Value.Content) jsonCount := 0 for _, contentTypeName := range SortedMapKeys { - if StringInArray(contentTypeName, contentTypesJSON) || util.IsMediaTypeJson(contentTypeName) { + if slices.Contains(contentTypesJSON, contentTypeName) || util.IsMediaTypeJson(contentTypeName) { jsonCount++ } } @@ -164,7 +166,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { switch { // JSON: - case StringInArray(contentTypeName, contentTypesJSON) || util.IsMediaTypeJson(contentTypeName): + case slices.Contains(contentTypesJSON, contentTypeName) || util.IsMediaTypeJson(contentTypeName): if typeDefinition.ContentTypeName == contentTypeName { caseAction := fmt.Sprintf("var dest %s\n"+ "if err := json.Unmarshal(bodyBytes, &dest); err != nil { \n"+ @@ -184,7 +186,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { } // YAML: - case StringInArray(contentTypeName, contentTypesYAML): + case slices.Contains(contentTypesYAML, contentTypeName): if typeDefinition.ContentTypeName == contentTypeName { caseAction := fmt.Sprintf("var dest %s\n"+ "if err := yaml.Unmarshal(bodyBytes, &dest); err != nil { \n"+ @@ -198,7 +200,7 @@ func genResponseUnmarshal(op *OperationDefinition) string { } // XML: - case StringInArray(contentTypeName, contentTypesXML): + case slices.Contains(contentTypesXML, contentTypeName): if typeDefinition.ContentTypeName == contentTypeName { caseAction := fmt.Sprintf("var dest %s\n"+ "if err := xml.Unmarshal(bodyBytes, &dest); err != nil { \n"+ diff --git a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl index 2aa164ddfd..59434aaef4 100644 --- a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl @@ -3,10 +3,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { diff --git a/pkg/codegen/typemapping.go b/pkg/codegen/typemapping.go index f5e20b54ac..2a54695f68 100644 --- a/pkg/codegen/typemapping.go +++ b/pkg/codegen/typemapping.go @@ -1,5 +1,7 @@ package codegen +import "maps" + // SimpleTypeSpec defines the Go type for an OpenAPI type/format combination, // along with any import required to use it. type SimpleTypeSpec struct { @@ -16,10 +18,10 @@ type FormatMapping struct { // TypeMapping defines the mapping from OpenAPI types to Go types. type TypeMapping struct { - Integer FormatMapping `yaml:"integer,omitempty" json:"integer,omitempty"` - Number FormatMapping `yaml:"number,omitempty" json:"number,omitempty"` - Boolean FormatMapping `yaml:"boolean,omitempty" json:"boolean,omitempty"` - String FormatMapping `yaml:"string,omitempty" json:"string,omitempty"` + Integer FormatMapping `yaml:"integer,omitempty" json:"integer"` + Number FormatMapping `yaml:"number,omitempty" json:"number"` + Boolean FormatMapping `yaml:"boolean,omitempty" json:"boolean"` + String FormatMapping `yaml:"string,omitempty" json:"string"` } // Merge returns a new TypeMapping with user overrides applied on top of base. @@ -39,9 +41,7 @@ func (base FormatMapping) merge(user FormatMapping) FormatMapping { } // Copy base formats - for k, v := range base.Formats { - result.Formats[k] = v - } + maps.Copy(result.Formats, base.Formats) // Override with user default if specified if user.Default.Type != "" { @@ -49,9 +49,7 @@ func (base FormatMapping) merge(user FormatMapping) FormatMapping { } // Override/add user formats - for k, v := range user.Formats { - result.Formats[k] = v - } + maps.Copy(result.Formats, user.Formats) return result } diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index b6fb91985f..fb921b58a2 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -15,13 +15,14 @@ package codegen import ( "bytes" + "cmp" "fmt" "go/token" + "maps" "net/url" "reflect" "regexp" "slices" - "sort" "strconv" "strings" "unicode" @@ -82,7 +83,7 @@ func (m NameNormalizerMap) Options() []string { options = append(options, string(key)) } - sort.Strings(options) + slices.Sort(options) return options } @@ -350,7 +351,7 @@ func SortedMapKeys[T any](m map[string]T) []string { for k := range m { keys = append(keys, k) } - sort.Strings(keys) + slices.Sort(keys) return keys } @@ -372,11 +373,11 @@ func SortedSchemaKeys(dict map[string]*openapi3.SchemaRef) []string { } } - sort.Slice(keys, func(i, j int) bool { - if i, j := orders[keys[i]], orders[keys[j]]; i != j { - return i < j - } - return keys[i] < keys[j] + slices.SortFunc(keys, func(a, b string) int { + return cmp.Or( + cmp.Compare(orders[a], orders[b]), + cmp.Compare(a, b), + ) }) return keys } @@ -405,24 +406,13 @@ func schemaXOrder(v *openapi3.SchemaRef) (int64, bool) { return 0, false } -// SortedParameterKeys returns sorted keys for a SecuritySchemeRef dict +// SortedSecuritySchemeKeys returns sorted keys for a SecuritySchemeRef dict func SortedSecuritySchemeKeys(dict map[string]*openapi3.SecuritySchemeRef) []string { - keys := make([]string, len(dict)) - i := 0 - for key := range dict { - keys[i] = key - i++ - } - sort.Strings(keys) + keys := slices.Collect(maps.Keys(dict)) + slices.Sort(keys) return keys } -// StringInArray checks whether the specified string is present in an array -// of strings -func StringInArray(str string, array []string) bool { - return slices.Contains(array, str) -} - // RefPathToObjName returns the name of referenced object without changes. // // #/components/schemas/Foo -> Foo @@ -1122,12 +1112,6 @@ func ParseGoImportExtension(v *openapi3.SchemaRef) (*goImport, error) { return &gi, nil } -func MergeImports(dst, src map[string]goImport) { - for k, v := range src { - dst[k] = v - } -} - // TypeDefinitionsEquivalent checks for equality between two type definitions, but // not every field is considered. We only want to know if they are fundamentally // the same type. @@ -1144,9 +1128,5 @@ func isAdditionalPropertiesExplicitFalse(s *openapi3.Schema) bool { return false } - return *s.AdditionalProperties.Has == false //nolint:staticcheck -} - -func sliceContains[E comparable](s []E, v E) bool { - return slices.Contains(s, v) + return !*s.AdditionalProperties.Has } From af135a92c7de0a98eedf9c916f4c618f8598d950 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 04:21:15 +0000 Subject: [PATCH 22/62] chore(deps): update release-drafter/release-drafter action to v7 (.github/workflows) (#2293) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Marcin Romaszewicz --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 36d0c96320..17a281c8cb 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@00ce30b0ce8a4d67bccfca59421cdf6c55dd0784 # v6.3.0 + - uses: release-drafter/release-drafter@139054aeaa9adc52ab36ddf67437541f039b88e2 # v7.1.1 with: name: next tag: next From a76544bd16ff78abe4bde9c9c682e1ef22e3a12d Mon Sep 17 00:00:00 2001 From: yoshiikipom Date: Sat, 4 Apr 2026 08:54:58 +0900 Subject: [PATCH 23/62] fix: avoid stack overflow errors when using heavily recursive types (#1377) As noted in #1373, we have cases where a heavily recursive `allOf` could lead to a stack overflow error. To avoid this, we can track the references that we've seen, and not recurse further if we have already traversed that ref. Closes #1373. Co-authored-by: Jamie Tanna --- internal/test/issues/issue-1373/config.yaml | 4 +++ internal/test/issues/issue-1373/generate.go | 3 ++ internal/test/issues/issue-1373/issue.gen.go | 15 +++++++++ internal/test/issues/issue-1373/spec.yaml | 32 ++++++++++++++++++++ pkg/codegen/merge_schemas.go | 23 ++++++++++---- pkg/codegen/merge_schemas_test.go | 12 ++++---- 6 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 internal/test/issues/issue-1373/config.yaml create mode 100644 internal/test/issues/issue-1373/generate.go create mode 100644 internal/test/issues/issue-1373/issue.gen.go create mode 100644 internal/test/issues/issue-1373/spec.yaml diff --git a/internal/test/issues/issue-1373/config.yaml b/internal/test/issues/issue-1373/config.yaml new file mode 100644 index 0000000000..2c5fe25659 --- /dev/null +++ b/internal/test/issues/issue-1373/config.yaml @@ -0,0 +1,4 @@ +package: issue1373 +generate: + models: true +output: issue.gen.go diff --git a/internal/test/issues/issue-1373/generate.go b/internal/test/issues/issue-1373/generate.go new file mode 100644 index 0000000000..fd0d2c74b7 --- /dev/null +++ b/internal/test/issues/issue-1373/generate.go @@ -0,0 +1,3 @@ +package issue1373 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue-1373/issue.gen.go b/internal/test/issues/issue-1373/issue.gen.go new file mode 100644 index 0000000000..0cd4cd8d85 --- /dev/null +++ b/internal/test/issues/issue-1373/issue.gen.go @@ -0,0 +1,15 @@ +// Package issue1373 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 issue1373 + +// NonRecursiveObject defines model for NonRecursiveObject. +type NonRecursiveObject struct { + FieldInNonRecursive *string `json:"FieldInNonRecursive,omitempty"` +} + +// RecursiveObject defines model for RecursiveObject. +type RecursiveObject struct { + FieldInNonRecursive *string `json:"FieldInNonRecursive,omitempty"` + FieldInRecursive *string `json:"FieldInRecursive:,omitempty"` +} diff --git a/internal/test/issues/issue-1373/spec.yaml b/internal/test/issues/issue-1373/spec.yaml new file mode 100644 index 0000000000..66bab84707 --- /dev/null +++ b/internal/test/issues/issue-1373/spec.yaml @@ -0,0 +1,32 @@ +openapi: 3.0.2 +info: + version: '0.0.1' + title: example + description: | + Make sure that recursive $ref in allOf are handled properly +paths: + /example: + get: + operationId: exampleGet + responses: + '200': + description: "OK" + content: + 'application/json': + schema: + $ref: '#/components/schemas/RecursiveObject' + +components: + schemas: + RecursiveObject: + allOf: + - $ref: "#/components/schemas/NonRecursiveObject" + - $ref: "#/components/schemas/RecursiveObject" + - properties: + FieldInRecursive:: + type: string + + NonRecursiveObject: + properties: + FieldInNonRecursive: + type: string diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index b9286703b3..b9d3af778a 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -38,7 +38,12 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) { if err != nil { return Schema{}, err } - schema, err = mergeOpenapiSchemas(schema, oneOfSchema, true) + + seenSchemaRef := make(map[string]bool) + if allOf[i].Ref != "" { + seenSchemaRef[allOf[i].Ref] = true + } + schema, err = mergeOpenapiSchemas(schema, oneOfSchema, true, seenSchemaRef) if err != nil { return Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err) } @@ -71,11 +76,17 @@ func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) { return schema, nil } -func mergeAllOf(allOf []*openapi3.SchemaRef) (openapi3.Schema, error) { +func mergeAllOf(allOf []*openapi3.SchemaRef, seenSchemaRef map[string]bool) (openapi3.Schema, error) { var schema openapi3.Schema for _, schemaRef := range allOf { var err error - schema, err = mergeOpenapiSchemas(schema, *schemaRef.Value, true) + if schemaRef.Ref != "" && seenSchemaRef[schemaRef.Ref] { + continue + } + if schemaRef.Ref != "" { + seenSchemaRef[schemaRef.Ref] = true + } + schema, err = mergeOpenapiSchemas(schema, *schemaRef.Value, true, seenSchemaRef) if err != nil { return openapi3.Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err) } @@ -85,7 +96,7 @@ func mergeAllOf(allOf []*openapi3.SchemaRef) (openapi3.Schema, error) { // mergeOpenapiSchemas merges two openAPI schemas and returns the schema // all of whose fields are composed. -func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, error) { +func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool, seenSchemaRef map[string]bool) (openapi3.Schema, error) { var result openapi3.Schema result.Extensions = make(map[string]any, len(s1.Extensions)+len(s2.Extensions)) @@ -100,7 +111,7 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, e var err error if s1.AllOf != nil { var merged openapi3.Schema - merged, err = mergeAllOf(s1.AllOf) + merged, err = mergeAllOf(s1.AllOf, seenSchemaRef) if err != nil { return openapi3.Schema{}, fmt.Errorf("error transitive merging AllOf on schema 1") } @@ -108,7 +119,7 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, e } if s2.AllOf != nil { var merged openapi3.Schema - merged, err = mergeAllOf(s2.AllOf) + merged, err = mergeAllOf(s2.AllOf, seenSchemaRef) if err != nil { return openapi3.Schema{}, fmt.Errorf("error transitive merging AllOf on schema 2") } diff --git a/pkg/codegen/merge_schemas_test.go b/pkg/codegen/merge_schemas_test.go index 9ba9a9f166..61fcbef125 100644 --- a/pkg/codegen/merge_schemas_test.go +++ b/pkg/codegen/merge_schemas_test.go @@ -17,7 +17,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{Discriminator: disc} s2 := openapi3.Schema{} - result, err := mergeOpenapiSchemas(s1, s2, true) + result, err := mergeOpenapiSchemas(s1, s2, true, make(map[string]bool)) require.NoError(t, err) assert.Equal(t, disc, result.Discriminator) }) @@ -26,7 +26,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{} s2 := openapi3.Schema{Discriminator: disc} - result, err := mergeOpenapiSchemas(s1, s2, true) + result, err := mergeOpenapiSchemas(s1, s2, true, make(map[string]bool)) require.NoError(t, err) assert.Equal(t, disc, result.Discriminator) }) @@ -36,7 +36,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{Discriminator: disc} s2 := openapi3.Schema{Discriminator: disc2} - _, err := mergeOpenapiSchemas(s1, s2, true) + _, err := mergeOpenapiSchemas(s1, s2, true, make(map[string]bool)) require.Error(t, err) assert.Contains(t, err.Error(), "discriminators") }) @@ -45,7 +45,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{} s2 := openapi3.Schema{} - result, err := mergeOpenapiSchemas(s1, s2, true) + result, err := mergeOpenapiSchemas(s1, s2, true, make(map[string]bool)) require.NoError(t, err) assert.Nil(t, result.Discriminator) }) @@ -54,7 +54,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{Discriminator: disc} s2 := openapi3.Schema{} - _, err := mergeOpenapiSchemas(s1, s2, false) + _, err := mergeOpenapiSchemas(s1, s2, false, make(map[string]bool)) require.Error(t, err) }) @@ -62,7 +62,7 @@ func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) { s1 := openapi3.Schema{} s2 := openapi3.Schema{Discriminator: disc} - _, err := mergeOpenapiSchemas(s1, s2, false) + _, err := mergeOpenapiSchemas(s1, s2, false, make(map[string]bool)) require.Error(t, err) }) } From 9ea3cc79a4c7c7863729bcc80485a1580797c90a Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Fri, 3 Apr 2026 17:49:43 -0700 Subject: [PATCH 24/62] Update release-drafter config for V7 (#2317) We no longer need to explicitly inherit release drafter settings from the org, and the V6 syntax no longer works, so I'm deleting the file. --- .github/release-drafter.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/release-drafter.yml diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index 852c651a59..0000000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1 +0,0 @@ -_extends: oapi-codegen/.github From 9aeaed3ce77629f295d845743a584d951f7a3c44 Mon Sep 17 00:00:00 2001 From: David Pollack Date: Wed, 8 Apr 2026 19:03:52 +0200 Subject: [PATCH 25/62] fix: add x-go-name for server urls (#2304) * fix: add x-go-name for server urls * Update pkg/codegen/server_urls.go do not swallow the extGoName error from automated review bot Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- examples/generate/serverurls/api.yaml | 4 ++++ examples/generate/serverurls/gen.go | 10 ++++++++++ examples/generate/serverurls/gen_test.go | 6 ++++++ pkg/codegen/server_urls.go | 22 +++++++++++++++++----- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/examples/generate/serverurls/api.yaml b/examples/generate/serverurls/api.yaml index 48695165ba..ec7c73a5e2 100644 --- a/examples/generate/serverurls/api.yaml +++ b/examples/generate/serverurls/api.yaml @@ -45,3 +45,7 @@ servers: description: some lowercase name # there may be URLs on their own, without a `description` - url: http://localhost:443 +# x-go-name overrides the auto-generated Go name +- url: https://api.example.com/v2 + description: Custom named server + x-go-name: MyCustomAPIServer diff --git a/examples/generate/serverurls/gen.go b/examples/generate/serverurls/gen.go index 79eace7a7a..b7d3485430 100644 --- a/examples/generate/serverurls/gen.go +++ b/examples/generate/serverurls/gen.go @@ -8,19 +8,29 @@ import ( "strings" ) +// MyCustomAPIServer defines the Server URL for Custom named server +const MyCustomAPIServer = "https://api.example.com/v2" + // ServerUrlDevelopmentServer defines the Server URL for Development server +const ServerUrlDevelopmentServer = "https://development.gigantic-server.com/v1" // ServerUrlDevelopmentServer1 defines the Server URL for Development server +const ServerUrlDevelopmentServer1 = "http://localhost:80" // ServerUrlDevelopmentServer2 defines the Server URL for Development server +const ServerUrlDevelopmentServer2 = "http://localhost:80" // ServerUrlHttplocalhost443 defines the Server URL for http://localhost:443 +const ServerUrlHttplocalhost443 = "http://localhost:443" // ServerUrlProductionServer defines the Server URL for Production server +const ServerUrlProductionServer = "https://api.gigantic-server.com/v1" // ServerUrlSomeLowercaseName defines the Server URL for some lowercase name +const ServerUrlSomeLowercaseName = "http://localhost:80" // ServerUrlStagingServer defines the Server URL for Staging server +const ServerUrlStagingServer = "https://staging.gigantic-server.com/v1" // ServerUrlTheProductionAPIServerBasePathVariable is the `basePath` variable for ServerUrlTheProductionAPIServer type ServerUrlTheProductionAPIServerBasePathVariable string diff --git a/examples/generate/serverurls/gen_test.go b/examples/generate/serverurls/gen_test.go index 2a2ecfb41a..573fb5f2e5 100644 --- a/examples/generate/serverurls/gen_test.go +++ b/examples/generate/serverurls/gen_test.go @@ -46,3 +46,9 @@ func TestServerUrlTheProductionAPIServer(t *testing.T) { assert.Equal(t, "https://demo.gigantic-server.com:8443/v2", serverUrl) }) } + +func TestXGoName(t *testing.T) { + t.Run("x-go-name overrides the auto-generated server name", func(t *testing.T) { + assert.Equal(t, "https://api.example.com/v2", MyCustomAPIServer) + }) +} diff --git a/pkg/codegen/server_urls.go b/pkg/codegen/server_urls.go index d10c2d9f60..48ef564d26 100644 --- a/pkg/codegen/server_urls.go +++ b/pkg/codegen/server_urls.go @@ -24,12 +24,24 @@ func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) names := make(map[string]*openapi3.Server) for _, server := range spec.Servers { - suffix := server.Description - if suffix == "" { - suffix = nameNormalizer(server.URL) + var name string + if goNameExt, ok := server.Extensions[extGoName]; ok { + customName, err := extParseGoFieldName(goNameExt) + if err != nil { + return "", fmt.Errorf("invalid value for %q: %w", extGoName, err) + } + if customName != "" { + name = customName + } + } + if name == "" { + suffix := server.Description + if suffix == "" { + suffix = nameNormalizer(server.URL) + } + name = serverURLPrefix + UppercaseFirstCharacter(suffix) + name = nameNormalizer(name) } - name := serverURLPrefix + UppercaseFirstCharacter(suffix) - name = nameNormalizer(name) // if this is the only type with this name, store it if _, conflict := names[name]; !conflict { From 9fffadedd3a520b20bd57cc2ece3fcfcb8d4bd9f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:39:38 -0700 Subject: [PATCH 26/62] fix(deps): update module github.com/getkin/kin-openapi to v0.135.0 (go.mod) (#2320) * fix(deps): update module github.com/getkin/kin-openapi to v0.135.0 (go.mod) * Tidy modules after kin update --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Marcin Romaszewicz --- examples/authenticated-api/stdhttp/go.mod | 6 +++--- examples/authenticated-api/stdhttp/go.sum | 12 ++++++------ examples/go.mod | 6 +++--- examples/go.sum | 12 ++++++------ examples/minimal-server/stdhttp/go.mod | 6 +++--- examples/minimal-server/stdhttp/go.sum | 12 ++++++------ examples/petstore-expanded/echo-v5/go.mod | 6 +++--- examples/petstore-expanded/echo-v5/go.sum | 12 ++++++------ examples/petstore-expanded/stdhttp/go.mod | 6 +++--- examples/petstore-expanded/stdhttp/go.sum | 12 ++++++------ go.mod | 6 +++--- go.sum | 12 ++++++------ internal/test/go.mod | 6 +++--- internal/test/go.sum | 12 ++++++------ internal/test/strict-server/stdhttp/go.mod | 6 +++--- internal/test/strict-server/stdhttp/go.sum | 12 ++++++------ 16 files changed, 72 insertions(+), 72 deletions(-) diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index f86436a306..fb23f089c8 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/lestrrat-go/jwx/v3 v3.0.13 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 @@ -30,8 +30,8 @@ require ( github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/segmentio/asm v1.2.1 // indirect diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index 0ad850b61a..cc925ce715 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -13,8 +13,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -78,10 +78,10 @@ github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/go.mod b/examples/go.mod index 9894cd261e..2f91e1b6f1 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../ require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/gin-gonic/gin v1.11.0 github.com/go-chi/chi/v5 v5.2.5 github.com/gofiber/fiber/v2 v2.52.12 @@ -82,8 +82,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/examples/go.sum b/examples/go.sum index a30c9a83b6..2b6bcbf2a5 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -50,8 +50,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= @@ -208,10 +208,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/minimal-server/stdhttp/go.mod b/examples/minimal-server/stdhttp/go.mod index acb4ea2c04..71f2290349 100644 --- a/examples/minimal-server/stdhttp/go.mod +++ b/examples/minimal-server/stdhttp/go.mod @@ -8,14 +8,14 @@ require github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-0000000000 require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getkin/kin-openapi v0.134.0 // indirect + github.com/getkin/kin-openapi v0.135.0 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect diff --git a/examples/minimal-server/stdhttp/go.sum b/examples/minimal-server/stdhttp/go.sum index f2ff34e742..f76bbdc4b8 100644 --- a/examples/minimal-server/stdhttp/go.sum +++ b/examples/minimal-server/stdhttp/go.sum @@ -11,8 +11,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -54,10 +54,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod index 09e9022013..b3a8f20752 100644 --- a/examples/petstore-expanded/echo-v5/go.mod +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -5,7 +5,7 @@ go 1.25.0 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/labstack/echo/v5 v5.0.4 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 @@ -24,8 +24,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum index 15fb93d7b0..dabb4bcc08 100644 --- a/examples/petstore-expanded/echo-v5/go.sum +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -69,10 +69,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index 481ce10be2..57f32bba62 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../ require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.2.0 @@ -24,8 +24,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index 9976dfce36..9878819024 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -69,10 +69,10 @@ github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+Lpmz github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/go.mod b/go.mod index d6c392af11..795c4bb8a3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.3 toolchain go1.24.4 require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/speakeasy-api/openapi-overlay v0.10.2 github.com/stretchr/testify v1.11.1 golang.org/x/mod v0.33.0 @@ -23,8 +23,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/go.sum b/go.sum index c7599ec79b..84f94478e9 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -54,10 +54,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/internal/test/go.mod b/internal/test/go.mod index 8f1d5e347a..394eba4890 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -5,7 +5,7 @@ go 1.24.3 replace github.com/oapi-codegen/oapi-codegen/v2 => ../../ require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/gin-gonic/gin v1.11.0 github.com/go-chi/chi/v5 v5.2.5 github.com/gofiber/fiber/v2 v2.52.12 @@ -70,8 +70,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/internal/test/go.sum b/internal/test/go.sum index 7153d67001..7c43e209da 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -48,8 +48,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= @@ -184,10 +184,10 @@ github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+ github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 18f7838442..d034f0a0f1 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -7,7 +7,7 @@ replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ replace github.com/oapi-codegen/oapi-codegen/v2/internal/test => ../.. require ( - github.com/getkin/kin-openapi v0.134.0 + github.com/getkin/kin-openapi v0.135.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/oapi-codegen/v2/internal/test v0.0.0-00010101000000-000000000000 github.com/oapi-codegen/runtime v1.3.1 @@ -25,8 +25,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c // indirect - github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/speakeasy-api/jsonpath v0.6.0 // indirect diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 743c6649a8..40349bbd97 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -15,8 +15,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.134.0 h1:/L5+1+kfe6dXh8Ot/wqiTgUkjOIEJiC0bbYVziHB8rU= -github.com/getkin/kin-openapi v0.134.0/go.mod h1:wK6ZLG/VgoETO9pcLJ/VmAtIcl/DNlMayNTb716EUxE= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= @@ -65,10 +65,10 @@ github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+ github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c h1:7ACFcSaQsrWtrH4WHHfUqE1C+f8r2uv8KGaW0jTNjus= -github.com/oasdiff/yaml v0.0.0-20260313112342-a3ea61cb4d4c/go.mod h1:JKox4Gszkxt57kj27u7rvi7IFoIULvCZHUsBTUmQM/s= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b h1:vivRhVUAa9t1q0Db4ZmezBP8pWQWnXHFokZj0AOea2g= -github.com/oasdiff/yaml3 v0.0.0-20260224194419-61cd415a242b/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= From 20bf6e117bf1ee4fbdcb5189ea1b3e0c0ef6c8f5 Mon Sep 17 00:00:00 2001 From: netixx Date: Thu, 9 Apr 2026 19:59:58 +0200 Subject: [PATCH 27/62] fix(deps): use updated import path for `github.com/speakeasy-api/openapi/overlay` (#2231) * Fix import path for overlay pkg * Update code and go.sum for overlay package The new overlay package has a small API change and we need to re-run go mod tidy on everything after rebasing. --------- Co-authored-by: Francois Espinet Co-authored-by: Marcin Romaszewicz --- examples/authenticated-api/stdhttp/go.mod | 4 ++-- examples/authenticated-api/stdhttp/go.sum | 19 ++++++++++++------- examples/go.mod | 4 ++-- examples/go.sum | 19 ++++++++++++------- examples/minimal-server/stdhttp/go.mod | 4 ++-- examples/minimal-server/stdhttp/go.sum | 19 ++++++++++++------- examples/petstore-expanded/echo-v5/go.mod | 4 ++-- examples/petstore-expanded/echo-v5/go.sum | 19 ++++++++++++------- examples/petstore-expanded/stdhttp/go.mod | 4 ++-- examples/petstore-expanded/stdhttp/go.sum | 19 ++++++++++++------- go.mod | 4 ++-- go.sum | 19 ++++++++++++------- internal/test/go.mod | 4 ++-- internal/test/go.sum | 19 ++++++++++++------- internal/test/strict-server/stdhttp/go.mod | 4 ++-- internal/test/strict-server/stdhttp/go.sum | 19 ++++++++++++------- pkg/util/loader.go | 4 ++-- 17 files changed, 114 insertions(+), 74 deletions(-) diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index fb23f089c8..d78e8862e0 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -35,8 +35,8 @@ require ( github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/segmentio/asm v1.2.1 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/valyala/fastjson v1.6.7 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index cc925ce715..de52d10215 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -48,11 +48,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA= github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38= @@ -99,14 +101,16 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -186,8 +190,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/go.mod b/examples/go.mod index 2f91e1b6f1..bb3606ee88 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -94,8 +94,8 @@ require ( github.com/schollz/closestmatch v2.1.0+incompatible // indirect github.com/segmentio/asm v1.2.1 // indirect github.com/sirupsen/logrus v1.9.1 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/tdewolff/minify/v2 v2.20.19 // indirect github.com/tdewolff/parse/v2 v2.7.12 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index 2b6bcbf2a5..290007b754 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -144,9 +144,12 @@ github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.15.1 h1:S9keusg26gZpjMmPqB5hOEvNKnmd1lNmcHrbbH2lnFs= github.com/labstack/echo/v4 v4.15.1/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= @@ -188,7 +191,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -238,6 +240,8 @@ github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= @@ -251,10 +255,10 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -402,8 +406,9 @@ google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7I google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/examples/minimal-server/stdhttp/go.mod b/examples/minimal-server/stdhttp/go.mod index 71f2290349..362bef5c56 100644 --- a/examples/minimal-server/stdhttp/go.mod +++ b/examples/minimal-server/stdhttp/go.mod @@ -17,8 +17,8 @@ require ( github.com/oasdiff/yaml v0.0.9 // indirect github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect golang.org/x/mod v0.33.0 // indirect diff --git a/examples/minimal-server/stdhttp/go.sum b/examples/minimal-server/stdhttp/go.sum index f76bbdc4b8..bb4e53d852 100644 --- a/examples/minimal-server/stdhttp/go.sum +++ b/examples/minimal-server/stdhttp/go.sum @@ -42,11 +42,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -75,12 +77,14 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -155,8 +159,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod index b3a8f20752..6e9281b491 100644 --- a/examples/petstore-expanded/echo-v5/go.mod +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -28,8 +28,8 @@ require ( github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect golang.org/x/mod v0.33.0 // indirect diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum index dabb4bcc08..824267217c 100644 --- a/examples/petstore-expanded/echo-v5/go.sum +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -51,11 +51,13 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v5 v5.0.4 h1:ll3I/O8BifjMztj9dD1vx/peZQv8cR2CTUdQK6QxGGc= github.com/labstack/echo/v5 v5.0.4/go.mod h1:SyvlSdObGjRXeQfCCXW/sybkZdOOQZBmpKF0bvALaeo= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= @@ -90,12 +92,14 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -174,8 +178,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index 57f32bba62..ed943eb926 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -28,8 +28,8 @@ require ( github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect golang.org/x/mod v0.33.0 // indirect diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index 9878819024..a3cede0861 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -51,11 +51,13 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -90,12 +92,14 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -172,8 +176,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/go.mod b/go.mod index 795c4bb8a3..4d5e7aff80 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.24.4 require ( github.com/getkin/kin-openapi v0.135.0 - github.com/speakeasy-api/openapi-overlay v0.10.2 + github.com/speakeasy-api/openapi v1.19.2 github.com/stretchr/testify v1.11.1 golang.org/x/mod v0.33.0 golang.org/x/text v0.34.0 @@ -27,7 +27,7 @@ require ( github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect diff --git a/go.sum b/go.sum index 84f94478e9..bb4e53d852 100644 --- a/go.sum +++ b/go.sum @@ -42,11 +42,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -75,12 +77,14 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -155,8 +159,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/internal/test/go.mod b/internal/test/go.mod index 394eba4890..c7ead48dc0 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -81,8 +81,8 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/closestmatch v2.1.0+incompatible // indirect github.com/sirupsen/logrus v1.9.1 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tdewolff/minify/v2 v2.20.19 // indirect github.com/tdewolff/parse/v2 v2.7.12 // indirect diff --git a/internal/test/go.sum b/internal/test/go.sum index 7c43e209da..2a53255d80 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -142,9 +142,12 @@ github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.15.1 h1:S9keusg26gZpjMmPqB5hOEvNKnmd1lNmcHrbbH2lnFs= github.com/labstack/echo/v4 v4.15.1/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= @@ -172,7 +175,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -213,6 +215,8 @@ github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQB github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= @@ -224,10 +228,10 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -371,8 +375,9 @@ google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7I google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index d034f0a0f1..3a14704185 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -29,8 +29,8 @@ require ( github.com/oasdiff/yaml3 v0.0.9 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/speakeasy-api/jsonpath v0.6.0 // indirect - github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect golang.org/x/mod v0.33.0 // indirect diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 40349bbd97..dc75c1b597 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -49,11 +49,13 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -86,12 +88,14 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= -github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -168,8 +172,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/pkg/util/loader.go b/pkg/util/loader.go index 7eea07b156..3a3264e832 100644 --- a/pkg/util/loader.go +++ b/pkg/util/loader.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3" - "github.com/speakeasy-api/openapi-overlay/pkg/loader" + "github.com/speakeasy-api/openapi/overlay/loader" "gopkg.in/yaml.v3" ) @@ -74,7 +74,7 @@ func LoadSwaggerWithOverlay(filePath string, opts LoadSwaggerWithOverlayOpts) (s } if opts.Strict { - err, vs := overlay.ApplyToStrict(&node) + vs, err := overlay.ApplyToStrict(&node) if err != nil { return nil, fmt.Errorf("failed to apply Overlay %#v to specification %#v: %v\nAdditionally, the following validation errors were found:\n- %s", opts.Path, filePath, err, strings.Join(vs, "\n- ")) } From cd4f5aa19861ac52f11cc1409eae4cab17aafc7b Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Sat, 11 Apr 2026 13:25:27 -0700 Subject: [PATCH 28/62] fix: allOf cycle detection oversight (#2316) PR #1377 was merged too early. This is a small follow-up tweak to make sure that #1373 is fixed properly. seed allOf[0] ref into cycle detection to prevent stack overflow when self-ref is first When the self-referencing $ref appears at position 0 in allOf, its ref was never added to seenSchemaRef. If s1's own AllOf contained a back-reference to itself, mergeAllOf would not detect the cycle. Seed allOf[0].Ref into a top-level seen set that is copied into each iteration's seenSchemaRef map, closing this gap. Co-authored-by: Claude Opus 4.6 (1M context) --- pkg/codegen/merge_schemas.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index b9d3af778a..1b21ae3e22 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -32,6 +32,13 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) { return Schema{}, err } + // Seed allOf[0]'s ref so that if s1's own AllOf contains a back-reference + // to itself, the cycle is detected during recursive merging. + seenTopLevel := make(map[string]bool) + if allOf[0].Ref != "" { + seenTopLevel[allOf[0].Ref] = true + } + for i := 1; i < n; i++ { var err error oneOfSchema, err := valueWithPropagatedRef(allOf[i]) @@ -40,8 +47,12 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) { } seenSchemaRef := make(map[string]bool) + for k := range seenTopLevel { + seenSchemaRef[k] = true + } if allOf[i].Ref != "" { seenSchemaRef[allOf[i].Ref] = true + seenTopLevel[allOf[i].Ref] = true } schema, err = mergeOpenapiSchemas(schema, oneOfSchema, true, seenSchemaRef) if err != nil { From 9107bfb7db47990e964e053bdd1f77196b80740a Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Sat, 11 Apr 2026 13:26:06 -0700 Subject: [PATCH 29/62] Add support for path aliases (#2312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for path aliases Closes #223 When an OpenAPI spec uses $ref to alias one path to another (e.g. /test2: $ref: '#/paths/~1test'), kin-openapi inlines the referenced path item into both entries. Previously this produced duplicate ServerInterface methods, wrapper functions, and type definitions — generating Go code that never compiled. Detect internal path aliases via PathItem.Ref (only when it starts with "#/paths/", to distinguish from external file references). For alias operations: - Server: skip interface method, wrapper, and strict handler generation. Route registration still emits both paths, pointing to the canonical wrapper via the new HandlerName() method on OperationDefinition. - Client: generate methods with a suffixed OperationId (e.g. GetTestAlias0) so each aliased path gets its own request builder targeting the correct URL. Co-Authored-By: Claude Opus 4.6 (1M context) * fix: skip operationId write-back for alias operations Alias paths share the same *openapi3.Operation pointer as the canonical path. Writing the suffixed alias name (e.g. GetTestAlias0) back to op.OperationID would corrupt the canonical operation's ID in the embedded spec. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- internal/test/pathalias/client-config.yaml | 5 + internal/test/pathalias/client.gen.go | 336 ++++++++++++++++++ internal/test/pathalias/doc.go | 4 + internal/test/pathalias/server-config.yaml | 6 + internal/test/pathalias/server.gen.go | 179 ++++++++++ internal/test/pathalias/spec.yaml | 28 ++ pkg/codegen/operations.go | 39 +- pkg/codegen/templates/chi/chi-handler.tmpl | 2 +- pkg/codegen/templates/chi/chi-interface.tmpl | 8 +- pkg/codegen/templates/chi/chi-middleware.tmpl | 4 +- .../templates/echo/echo-interface.tmpl | 4 +- pkg/codegen/templates/echo/echo-register.tmpl | 2 +- pkg/codegen/templates/echo/echo-wrappers.tmpl | 4 +- .../templates/echo/v5/echo-interface.tmpl | 4 +- .../templates/echo/v5/echo-register.tmpl | 2 +- .../templates/echo/v5/echo-wrappers.tmpl | 4 +- .../templates/fiber/fiber-handler.tmpl | 2 +- .../templates/fiber/fiber-interface.tmpl | 4 +- .../templates/fiber/fiber-middleware.tmpl | 4 +- pkg/codegen/templates/gin/gin-interface.tmpl | 4 +- pkg/codegen/templates/gin/gin-register.tmpl | 2 +- pkg/codegen/templates/gin/gin-wrappers.tmpl | 4 +- .../templates/gorilla/gorilla-interface.tmpl | 4 +- .../templates/gorilla/gorilla-middleware.tmpl | 4 +- .../templates/gorilla/gorilla-register.tmpl | 2 +- pkg/codegen/templates/iris/iris-handler.tmpl | 2 +- .../templates/iris/iris-interface.tmpl | 4 +- .../templates/iris/iris-middleware.tmpl | 4 +- .../templates/stdhttp/std-http-handler.tmpl | 2 +- .../templates/stdhttp/std-http-interface.tmpl | 4 +- .../stdhttp/std-http-middleware.tmpl | 4 +- pkg/codegen/templates/strict/strict-echo.tmpl | 2 + .../templates/strict/strict-echo5.tmpl | 2 + .../strict/strict-fiber-interface.tmpl | 8 +- .../templates/strict/strict-fiber.tmpl | 2 + pkg/codegen/templates/strict/strict-gin.tmpl | 2 + pkg/codegen/templates/strict/strict-http.tmpl | 2 + .../templates/strict/strict-interface.tmpl | 8 +- .../strict/strict-iris-interface.tmpl | 8 +- pkg/codegen/templates/strict/strict-iris.tmpl | 2 + 40 files changed, 661 insertions(+), 56 deletions(-) create mode 100644 internal/test/pathalias/client-config.yaml create mode 100644 internal/test/pathalias/client.gen.go create mode 100644 internal/test/pathalias/doc.go create mode 100644 internal/test/pathalias/server-config.yaml create mode 100644 internal/test/pathalias/server.gen.go create mode 100644 internal/test/pathalias/spec.yaml diff --git a/internal/test/pathalias/client-config.yaml b/internal/test/pathalias/client-config.yaml new file mode 100644 index 0000000000..d191dfa49d --- /dev/null +++ b/internal/test/pathalias/client-config.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: pathalias +generate: + client: true +output: client.gen.go diff --git a/internal/test/pathalias/client.gen.go b/internal/test/pathalias/client.gen.go new file mode 100644 index 0000000000..d1ee30f777 --- /dev/null +++ b/internal/test/pathalias/client.gen.go @@ -0,0 +1,336 @@ +// Package pathalias 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 pathalias + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" +) + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetTest request + GetTest(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetTestAlias0 request + GetTestAlias0(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetTest(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetTestRequest(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 *Client) GetTestAlias0(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetTestAlias0Request(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) +} + +// NewGetTestRequest generates requests for GetTest +func NewGetTestRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/test") + 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 +} + +// NewGetTestAlias0Request generates requests for GetTestAlias0 +func NewGetTestAlias0Request(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/test2") + 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 *Client) 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 *Client) 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 { + // GetTestWithResponse request + GetTestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestResponse, error) + + // GetTestAlias0WithResponse request + GetTestAlias0WithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestAlias0Response, error) +} + +type GetTestResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *B +} + +// Status returns HTTPResponse.Status +func (r GetTestResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetTestResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetTestAlias0Response struct { + Body []byte + HTTPResponse *http.Response + JSON200 *B +} + +// Status returns HTTPResponse.Status +func (r GetTestAlias0Response) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetTestAlias0Response) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetTestWithResponse request returning *GetTestResponse +func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { + rsp, err := c.GetTest(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetTestResponse(rsp) +} + +// GetTestAlias0WithResponse request returning *GetTestAlias0Response +func (c *ClientWithResponses) GetTestAlias0WithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestAlias0Response, error) { + rsp, err := c.GetTestAlias0(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetTestAlias0Response(rsp) +} + +// ParseGetTestResponse parses an HTTP response from a GetTestWithResponse call +func ParseGetTestResponse(rsp *http.Response) (*GetTestResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetTestResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest B + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetTestAlias0Response parses an HTTP response from a GetTestAlias0WithResponse call +func ParseGetTestAlias0Response(rsp *http.Response) (*GetTestAlias0Response, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetTestAlias0Response{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest B + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} diff --git a/internal/test/pathalias/doc.go b/internal/test/pathalias/doc.go new file mode 100644 index 0000000000..a88f063e40 --- /dev/null +++ b/internal/test/pathalias/doc.go @@ -0,0 +1,4 @@ +package pathalias + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server-config.yaml spec.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=client-config.yaml spec.yaml diff --git a/internal/test/pathalias/server-config.yaml b/internal/test/pathalias/server-config.yaml new file mode 100644 index 0000000000..d4a4de5248 --- /dev/null +++ b/internal/test/pathalias/server-config.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: pathalias +generate: + chi-server: true + models: true +output: server.gen.go diff --git a/internal/test/pathalias/server.gen.go b/internal/test/pathalias/server.gen.go new file mode 100644 index 0000000000..2883b80b82 --- /dev/null +++ b/internal/test/pathalias/server.gen.go @@ -0,0 +1,179 @@ +// Package pathalias 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 pathalias + +import ( + "fmt" + "net/http" + + "github.com/go-chi/chi/v5" +) + +// B defines model for B. +type B struct { + A *string `json:"A,omitempty"` +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + // test + // (GET /test) + GetTest(w http.ResponseWriter, r *http.Request) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// test +// (GET /test) +func (_ Unimplemented) GetTest(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// 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 + +// GetTest operation middleware +func (siw *ServerInterfaceWrapper) GetTest(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetTest(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, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + 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, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + 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, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/test", wrapper.GetTest) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/test2", wrapper.GetTest) + }) + + return r +} diff --git a/internal/test/pathalias/spec.yaml b/internal/test/pathalias/spec.yaml new file mode 100644 index 0000000000..f7b0a3b9f5 --- /dev/null +++ b/internal/test/pathalias/spec.yaml @@ -0,0 +1,28 @@ +openapi: "3.0.1" +info: + title: test + description: API description. + version: 0.1.0 +servers: [] +paths: + /test: + get: + summary: test + operationId: getTest + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/B" + /test2: + $ref: "#/paths/~1test" + +components: + schemas: + B: + type: object + properties: + A: + type: string diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 436c46d178..d9bf1dcbfb 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -270,6 +270,18 @@ type OperationDefinition struct { Method string // GET, POST, DELETE, etc. Path string // The Swagger path for the operation, like /resource/{id} Spec *openapi3.Operation + IsAlias bool // True when this path is a $ref alias of another path item + AliasTarget string // When IsAlias is true, this is the OperationId of the canonical operation (for route registration to reference the correct wrapper) +} + +// HandlerName returns the OperationId to use when referencing the server-side +// wrapper function. For alias operations this is the canonical operation's ID, +// since the alias doesn't generate its own wrapper. +func (o *OperationDefinition) HandlerName() string { + if o.IsAlias { + return o.AliasTarget + } + return o.OperationId } // Params returns the list of all parameters except Path parameters. Path parameters @@ -608,6 +620,10 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { return operations, nil } + // Track alias counters for generating unique client method names + // when multiple paths $ref the same path item. + aliasCounters := map[string]int{} + for _, requestPath := range SortedMapKeys(swagger.Paths.Map()) { pathItem := swagger.Paths.Value(requestPath) // These are parameters defined for all methods on a given path. They @@ -641,8 +657,25 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { } operationId = typeNamePrefix(operationId) + operationId - if !globalState.options.Compatibility.PreserveOriginalOperationIdCasingInEmbeddedSpec { - // update the existing, shared, copy of the spec if we're not wanting to preserve it + // Detect path aliases: when a path item has an internal $ref + // pointing to another path in the same document (e.g. + // "#/paths/~1test"), it's a duplicate that would produce + // identical server methods. External $refs (pointing to other + // files) are not aliases — they're the sole definition of + // that path, just stored externally. + isAlias := strings.HasPrefix(pathItem.Ref, "#/paths/") + var aliasTarget string + if isAlias { + aliasTarget = nameNormalizer(operationId) + n := aliasCounters[operationId] + aliasCounters[operationId] = n + 1 + operationId = operationId + fmt.Sprintf("Alias%d", n) + } + + if !globalState.options.Compatibility.PreserveOriginalOperationIdCasingInEmbeddedSpec && !isAlias { + // update the existing, shared, copy of the spec if we're not wanting to preserve it. + // Skip for aliases: they share the same *Operation as the canonical path, + // and writing the suffixed name back would corrupt the original. op.OperationID = operationId } @@ -699,6 +732,8 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { Bodies: bodyDefinitions, Responses: responseDefinitions, TypeDefinitions: typeDefinitions, + IsAlias: isAlias, + AliasTarget: aliasTarget, } // check for overrides of SecurityDefinitions. diff --git a/pkg/codegen/templates/chi/chi-handler.tmpl b/pkg/codegen/templates/chi/chi-handler.tmpl index 113e4d7ada..72c57a6be6 100644 --- a/pkg/codegen/templates/chi/chi-handler.tmpl +++ b/pkg/codegen/templates/chi/chi-handler.tmpl @@ -43,7 +43,7 @@ ErrorHandlerFunc: options.ErrorHandlerFunc, } {{end}} {{range .}}r.Group(func(r chi.Router) { -r.{{.Method | lower | title }}(options.BaseURL+"{{.Path | swaggerUriToChiUri}}", wrapper.{{.OperationId}}) +r.{{.Method | lower | title }}(options.BaseURL+"{{.Path | swaggerUriToChiUri}}", wrapper.{{.HandlerName}}) }) {{end}} return r diff --git a/pkg/codegen/templates/chi/chi-interface.tmpl b/pkg/codegen/templates/chi/chi-interface.tmpl index cfc393bde2..bec8452e75 100644 --- a/pkg/codegen/templates/chi/chi-interface.tmpl +++ b/pkg/codegen/templates/chi/chi-interface.tmpl @@ -1,17 +1,17 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) -{{end}} +{{end}}{{end}} } // Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. type Unimplemented struct {} - {{range .}}{{.SummaryAsComment }} + {{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) func (_ Unimplemented) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { w.WriteHeader(http.StatusNotImplemented) } - {{end}} \ No newline at end of file + {{end}}{{end}} \ No newline at end of file diff --git a/pkg/codegen/templates/chi/chi-middleware.tmpl b/pkg/codegen/templates/chi/chi-middleware.tmpl index c3e7cf82ae..347b1dd95d 100644 --- a/pkg/codegen/templates/chi/chi-middleware.tmpl +++ b/pkg/codegen/templates/chi/chi-middleware.tmpl @@ -8,7 +8,7 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc func(http.Handler) http.Handler {{range .}}{{$opid := .OperationId}} - +{{if not .IsAlias}} // {{$opid}} operation middleware func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} @@ -194,7 +194,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -{{end}} +{{end}}{{end}} type UnescapedCookieParamError struct { ParamName string diff --git a/pkg/codegen/templates/echo/echo-interface.tmpl b/pkg/codegen/templates/echo/echo-interface.tmpl index 7380091690..6834432709 100644 --- a/pkg/codegen/templates/echo/echo-interface.tmpl +++ b/pkg/codegen/templates/echo/echo-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(ctx echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/echo/echo-register.tmpl b/pkg/codegen/templates/echo/echo-register.tmpl index 21b52fe48b..dcfeb54f18 100644 --- a/pkg/codegen/templates/echo/echo-register.tmpl +++ b/pkg/codegen/templates/echo/echo-register.tmpl @@ -28,6 +28,6 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL Handler: si, } {{end}} -{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.OperationId}}) +{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}) {{end}} } diff --git a/pkg/codegen/templates/echo/echo-wrappers.tmpl b/pkg/codegen/templates/echo/echo-wrappers.tmpl index a086d75d4e..064bd7f32f 100644 --- a/pkg/codegen/templates/echo/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/echo-wrappers.tmpl @@ -3,7 +3,7 @@ type ServerInterfaceWrapper struct { Handler ServerInterface } -{{range .}}{{$opid := .OperationId}}// {{$opid}} converts echo context to params. +{{range .}}{{$opid := .OperationId}}{{if not .IsAlias}}// {{$opid}} converts echo context to params. func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error { var err error {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- @@ -128,4 +128,4 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error { err = w.Handler.{{.OperationId}}(ctx{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) return err } -{{end}} +{{end}}{{end}} diff --git a/pkg/codegen/templates/echo/v5/echo-interface.tmpl b/pkg/codegen/templates/echo/v5/echo-interface.tmpl index 1531eef866..6d5b874bed 100644 --- a/pkg/codegen/templates/echo/v5/echo-interface.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/echo/v5/echo-register.tmpl b/pkg/codegen/templates/echo/v5/echo-register.tmpl index 78de21b83e..bd0e968b0f 100644 --- a/pkg/codegen/templates/echo/v5/echo-register.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-register.tmpl @@ -28,6 +28,6 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL Handler: si, } {{end}} -{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.OperationId}}) +{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}) {{end}} } diff --git a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl index 9f7d608dda..c061240df3 100644 --- a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl @@ -3,7 +3,7 @@ type ServerInterfaceWrapper struct { Handler ServerInterface } -{{range .}}{{$opid := .OperationId}}// {{$opid}} converts echo context to params. +{{range .}}{{$opid := .OperationId}}{{if not .IsAlias}}// {{$opid}} converts echo context to params. func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { var err error {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- @@ -128,4 +128,4 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { err = w.Handler.{{.OperationId}}(ctx{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) return err } -{{end}} +{{end}}{{end}} diff --git a/pkg/codegen/templates/fiber/fiber-handler.tmpl b/pkg/codegen/templates/fiber/fiber-handler.tmpl index 46aab9607d..5ac8be929f 100644 --- a/pkg/codegen/templates/fiber/fiber-handler.tmpl +++ b/pkg/codegen/templates/fiber/fiber-handler.tmpl @@ -22,6 +22,6 @@ for _, m := range options.Middlewares { } {{end}} {{range .}} -router.{{.Method | lower | title }}(options.BaseURL+"{{.Path | swaggerUriToFiberUri}}", wrapper.{{.OperationId}}) +router.{{.Method | lower | title }}(options.BaseURL+"{{.Path | swaggerUriToFiberUri}}", wrapper.{{.HandlerName}}) {{end}} } diff --git a/pkg/codegen/templates/fiber/fiber-interface.tmpl b/pkg/codegen/templates/fiber/fiber-interface.tmpl index 8ef90a851a..4459e8b0d6 100644 --- a/pkg/codegen/templates/fiber/fiber-interface.tmpl +++ b/pkg/codegen/templates/fiber/fiber-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(c *fiber.Ctx{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index 5fcbe41383..002d144101 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -8,7 +8,7 @@ type MiddlewareFunc fiber.Handler type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error {{range .}}{{$opid := .OperationId}} - +{{if not .IsAlias}} // {{$opid}} operation middleware func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { @@ -184,4 +184,4 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { return handler(c) } -{{end}} +{{end}}{{end}} diff --git a/pkg/codegen/templates/gin/gin-interface.tmpl b/pkg/codegen/templates/gin/gin-interface.tmpl index 49a18f812a..dec255e713 100644 --- a/pkg/codegen/templates/gin/gin-interface.tmpl +++ b/pkg/codegen/templates/gin/gin-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(c *gin.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/gin/gin-register.tmpl b/pkg/codegen/templates/gin/gin-register.tmpl index 8f03722ab1..4bc17b3c74 100644 --- a/pkg/codegen/templates/gin/gin-register.tmpl +++ b/pkg/codegen/templates/gin/gin-register.tmpl @@ -28,6 +28,6 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options {{end}} {{range . -}} - router.{{.Method }}(options.BaseURL+"{{.Path | swaggerUriToGinUri }}", wrapper.{{.OperationId}}) + router.{{.Method }}(options.BaseURL+"{{.Path | swaggerUriToGinUri }}", wrapper.{{.HandlerName}}) {{end -}} } diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl index e18c0d644c..872590fa7a 100644 --- a/pkg/codegen/templates/gin/gin-wrappers.tmpl +++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl @@ -8,7 +8,7 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc func(c *gin.Context) {{range .}}{{$opid := .OperationId}} - +{{if not .IsAlias}} // {{$opid}} operation middleware func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { @@ -183,4 +183,4 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { siw.Handler.{{.OperationId}}(c{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) } -{{end}} +{{end}}{{end}} diff --git a/pkg/codegen/templates/gorilla/gorilla-interface.tmpl b/pkg/codegen/templates/gorilla/gorilla-interface.tmpl index 79a51fd75b..04baa51e39 100644 --- a/pkg/codegen/templates/gorilla/gorilla-interface.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl index 6a1b18ce2d..1624a7ed6a 100644 --- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl @@ -8,7 +8,7 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc func(http.Handler) http.Handler {{range .}}{{$opid := .OperationId}} - +{{if not .IsAlias}} // {{$opid}} operation middleware func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} @@ -194,7 +194,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -{{end}} +{{end}}{{end}} type UnescapedCookieParamError struct { ParamName string diff --git a/pkg/codegen/templates/gorilla/gorilla-register.tmpl b/pkg/codegen/templates/gorilla/gorilla-register.tmpl index 28e8ff2720..b16f3fc9fc 100644 --- a/pkg/codegen/templates/gorilla/gorilla-register.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-register.tmpl @@ -43,7 +43,7 @@ ErrorHandlerFunc: options.ErrorHandlerFunc, } {{end}} {{range .}} -r.HandleFunc(options.BaseURL+"{{.Path | swaggerUriToGorillaUri }}", wrapper.{{.OperationId}}).Methods({{.Method | httpMethodConstant}}) +r.HandleFunc(options.BaseURL+"{{.Path | swaggerUriToGorillaUri }}", wrapper.{{.HandlerName}}).Methods({{.Method | httpMethodConstant}}) {{end}} return r } diff --git a/pkg/codegen/templates/iris/iris-handler.tmpl b/pkg/codegen/templates/iris/iris-handler.tmpl index 3f1228faea..c0c5b23cc5 100644 --- a/pkg/codegen/templates/iris/iris-handler.tmpl +++ b/pkg/codegen/templates/iris/iris-handler.tmpl @@ -17,7 +17,7 @@ func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, o Handler: si, } {{end}} -{{range .}}router.{{.Method | lower | title}}(options.BaseURL + "{{.Path | swaggerUriToIrisUri}}", wrapper.{{.OperationId}}) +{{range .}}router.{{.Method | lower | title}}(options.BaseURL + "{{.Path | swaggerUriToIrisUri}}", wrapper.{{.HandlerName}}) {{end}} router.Build() } diff --git a/pkg/codegen/templates/iris/iris-interface.tmpl b/pkg/codegen/templates/iris/iris-interface.tmpl index fb53a124b9..78f401ec2c 100644 --- a/pkg/codegen/templates/iris/iris-interface.tmpl +++ b/pkg/codegen/templates/iris/iris-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(ctx iris.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/iris/iris-middleware.tmpl b/pkg/codegen/templates/iris/iris-middleware.tmpl index 7ee4ce9b2b..2a6cfaa769 100644 --- a/pkg/codegen/templates/iris/iris-middleware.tmpl +++ b/pkg/codegen/templates/iris/iris-middleware.tmpl @@ -5,7 +5,7 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc iris.Handler -{{range .}}{{$opid := .OperationId}}// {{$opid}} converts iris context to params. +{{range .}}{{$opid := .OperationId}}{{if not .IsAlias}}// {{$opid}} converts iris context to params. func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error @@ -158,4 +158,4 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { // Invoke the callback with all the unmarshaled arguments w.Handler.{{.OperationId}}(ctx{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}}) } -{{end}} +{{end}}{{end}} diff --git a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl index 59434aaef4..63fccd2445 100644 --- a/pkg/codegen/templates/stdhttp/std-http-handler.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-handler.tmpl @@ -49,7 +49,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } {{end}} -{{range .}}m.HandleFunc({{.Method | httpMethodConstant}}+" "+options.BaseURL+"{{.Path | swaggerUriToStdHttpUri}}", wrapper.{{.OperationId}}) +{{range .}}m.HandleFunc({{.Method | httpMethodConstant}}+" "+options.BaseURL+"{{.Path | swaggerUriToStdHttpUri}}", wrapper.{{.HandlerName}}) {{end}} return m } diff --git a/pkg/codegen/templates/stdhttp/std-http-interface.tmpl b/pkg/codegen/templates/stdhttp/std-http-interface.tmpl index 79a51fd75b..04baa51e39 100644 --- a/pkg/codegen/templates/stdhttp/std-http-interface.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-interface.tmpl @@ -1,7 +1,7 @@ // ServerInterface represents all server handlers. type ServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) -{{end}} +{{end}}{{end}} } diff --git a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl index fbccc40a03..daadd981a7 100644 --- a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl @@ -8,7 +8,7 @@ type ServerInterfaceWrapper struct { type MiddlewareFunc func(http.Handler) http.Handler {{range .}}{{$opid := .OperationId}} - +{{if not .IsAlias}} // {{$opid}} operation middleware func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} @@ -194,7 +194,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -{{end}} +{{end}}{{end}} type UnescapedCookieParamError struct { ParamName string diff --git a/pkg/codegen/templates/strict/strict-echo.tmpl b/pkg/codegen/templates/strict/strict-echo.tmpl index 7b470c8ce7..f8b523fa91 100644 --- a/pkg/codegen/templates/strict/strict-echo.tmpl +++ b/pkg/codegen/templates/strict/strict-echo.tmpl @@ -12,6 +12,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(ctx echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error { var request {{$opid | ucFirst}}RequestObject @@ -107,4 +108,5 @@ type strictHandler struct { } return nil } + {{end}} {{end}} diff --git a/pkg/codegen/templates/strict/strict-echo5.tmpl b/pkg/codegen/templates/strict/strict-echo5.tmpl index 5afb443606..1073714599 100644 --- a/pkg/codegen/templates/strict/strict-echo5.tmpl +++ b/pkg/codegen/templates/strict/strict-echo5.tmpl @@ -12,6 +12,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(ctx *echo.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error { var request {{$opid | ucFirst}}RequestObject @@ -94,4 +95,5 @@ type strictHandler struct { } return nil } + {{end}} {{end}} diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index e83f7e38aa..11d1cbaad0 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -1,4 +1,4 @@ -{{range .}} +{{range .}}{{if not .IsAlias}} {{$opid := .OperationId -}} type {{$opid | ucFirst}}RequestObject struct { {{range .PathParams -}} @@ -133,13 +133,13 @@ } {{end}} {{end}} -{{end}} +{{end}}{{end}} // StrictServerInterface represents all server handlers. type StrictServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) -{{end}}{{/* range . */ -}} +{{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-fiber.tmpl b/pkg/codegen/templates/strict/strict-fiber.tmpl index 59a2c0736b..106f33a766 100644 --- a/pkg/codegen/templates/strict/strict-fiber.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber.tmpl @@ -13,6 +13,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(ctx *fiber.Ctx{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error { var request {{$opid | ucFirst}}RequestObject @@ -100,4 +101,5 @@ type strictHandler struct { } return nil } + {{end}} {{end}} diff --git a/pkg/codegen/templates/strict/strict-gin.tmpl b/pkg/codegen/templates/strict/strict-gin.tmpl index 40a7b7bcb1..86040d6d76 100644 --- a/pkg/codegen/templates/strict/strict-gin.tmpl +++ b/pkg/codegen/templates/strict/strict-gin.tmpl @@ -12,6 +12,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(ctx *gin.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { var request {{$opid | ucFirst}}RequestObject @@ -118,4 +119,5 @@ type strictHandler struct { ctx.Error(fmt.Errorf("unexpected response type: %T", response)) } } + {{end}} {{end}} diff --git a/pkg/codegen/templates/strict/strict-http.tmpl b/pkg/codegen/templates/strict/strict-http.tmpl index 7314c26fd7..d55341ca0b 100644 --- a/pkg/codegen/templates/strict/strict-http.tmpl +++ b/pkg/codegen/templates/strict/strict-http.tmpl @@ -29,6 +29,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(w http.ResponseWriter, r *http.Request{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { var request {{$opid | ucFirst}}RequestObject @@ -132,4 +133,5 @@ type strictHandler struct { sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) } } + {{end}} {{end}} diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index ab56514e8a..f6108de7a9 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -1,4 +1,4 @@ -{{range .}} +{{range .}}{{if not .IsAlias}} {{$opid := .OperationId -}} type {{$opid | ucFirst}}RequestObject struct { {{range .PathParams -}} @@ -151,13 +151,13 @@ } {{end}} {{end}} -{{end}} +{{end}}{{end}} // StrictServerInterface represents all server handlers. type StrictServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) -{{end}}{{/* range . */ -}} +{{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 95b78d0645..aa7e166d9f 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -1,4 +1,4 @@ -{{range .}} +{{range .}}{{if not .IsAlias}} {{$opid := .OperationId -}} type {{$opid | ucFirst}}RequestObject struct { {{range .PathParams -}} @@ -135,13 +135,13 @@ } {{end}} {{end}} -{{end}} +{{end}}{{end}} // StrictServerInterface represents all server handlers. type StrictServerInterface interface { -{{range .}}{{.SummaryAsComment }} +{{range .}}{{if not .IsAlias}}{{.SummaryAsComment }} // ({{.Method}} {{.Path}}) {{$opid := .OperationId -}} {{$opid}}(ctx context.Context, request {{$opid | ucFirst}}RequestObject) ({{$opid | ucFirst}}ResponseObject, error) -{{end}}{{/* range . */ -}} +{{end}}{{end}}{{/* range . */ -}} } diff --git a/pkg/codegen/templates/strict/strict-iris.tmpl b/pkg/codegen/templates/strict/strict-iris.tmpl index 6ed301574c..804efb0cf3 100644 --- a/pkg/codegen/templates/strict/strict-iris.tmpl +++ b/pkg/codegen/templates/strict/strict-iris.tmpl @@ -12,6 +12,7 @@ type strictHandler struct { {{range .}} {{$opid := .OperationId}} + {{if not .IsAlias}} // {{$opid}} operation middleware func (sh *strictHandler) {{.OperationId}}(ctx iris.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) { var request {{$opid | ucFirst}}RequestObject @@ -118,4 +119,5 @@ type strictHandler struct { return } } + {{end}} {{end}} From a4c36dc26466d4d96dd985900a87101efd8ba66c Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Sat, 11 Apr 2026 13:31:26 -0700 Subject: [PATCH 30/62] support optional/nullable response headers (#2301) * support optional/nullable response headers Closes: #2267 Response headers in strict server code were always generated as direct value types regardless of whether they were required. This adds support for optional and nullable response headers in the strict-interface and strict-responses templates. Add Required and Nullable fields to ResponseHeaderDefinition, populated from the OpenAPI header object. Add GoTypeDef(), IsOptional(), and IsNullable() methods that mirror the existing Property logic for determining whether a field should be a pointer, nullable.Nullable[T], or a direct value. Update strict-interface.tmpl and strict-responses.tmpl to use GoTypeDef for struct field types, and to conditionally guard w.Header().Set() calls with nil/IsSpecified checks for optional/nullable headers. Note: this is a breaking change for specs where response headers lack explicit `required: true`, since the OpenAPI default is false. Existing headers will change from direct values to pointers. This may need to be gated behind a config option. Co-Authored-By: Claude Opus 4.6 (1M context) * Add HeadersImplicitlyRequired compatibility flag for #2267 Allows users to restore the pre-v2.5.0 behavior where all response headers are treated as required, ignoring the OpenAPI `required` field. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- configuration-schema.json | 4 ++ internal/test/issues/issue-1676/ping.gen.go | 6 ++- .../issue.gen.go | 2 +- internal/test/strict-server/chi/server.gen.go | 51 +++++++++++-------- .../test/strict-server/echo/server.gen.go | 51 +++++++++++-------- .../test/strict-server/fiber/server.gen.go | 47 +++++++++-------- internal/test/strict-server/gin/server.gen.go | 51 +++++++++++-------- .../test/strict-server/gorilla/server.gen.go | 51 +++++++++++-------- .../test/strict-server/iris/server.gen.go | 47 +++++++++-------- .../test/strict-server/stdhttp/server.gen.go | 51 +++++++++++-------- .../test/strict-server/strict-schema.yaml | 14 +++++ pkg/codegen/configuration.go | 10 ++++ pkg/codegen/operations.go | 49 ++++++++++++++++-- .../templates/strict/strict-interface.tmpl | 38 ++++++++++++-- .../templates/strict/strict-responses.tmpl | 2 +- 15 files changed, 315 insertions(+), 159 deletions(-) diff --git a/configuration-schema.json b/configuration-schema.json index ff325c1f6e..21bfb0c0d5 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -115,6 +115,10 @@ "preserve-original-operation-id-casing-in-embedded-spec": { "type": "boolean", "description": "When `oapi-codegen` parses the original OpenAPI specification, it will apply the configured `output-options.name-normalizer` to each operation's `operationId` before that is used to generate code from.\nHowever, this is also applied to the copy of the `operationId`s in the `embedded-spec` generation, which means that the embedded OpenAPI specification is then out-of-sync with the input specificiation.\nTo ensure that the `operationId` in the embedded spec is preserved as-is from the input specification, set this. NOTE that this will not impact generated code.\nNOTE that if you're using `include-operation-ids` or `exclude-operation-ids` you may want to ensure that the `operationId`s used are correct." + }, + "headers-implicitly-required": { + "type": "boolean", + "description": "Treats all response headers as required, ignoring the `required` property from the header definition. Prior to v2.6.0, oapi-codegen generated all response headers as direct values (implicitly required). The OpenAPI specification defaults headers to optional (required: false), so the corrected behavior generates optional headers as pointers. Set this to true to restore the old behavior where all headers are treated as required.\nPlease see https://github.com/oapi-codegen/oapi-codegen/issues/2267" } } }, diff --git a/internal/test/issues/issue-1676/ping.gen.go b/internal/test/issues/issue-1676/ping.gen.go index 53fa480501..395033a2ba 100644 --- a/internal/test/issues/issue-1676/ping.gen.go +++ b/internal/test/issues/issue-1676/ping.gen.go @@ -168,7 +168,7 @@ type GetPingResponseObject interface { } type GetPing200ResponseHeaders struct { - MyHeader string + MyHeader *string } type GetPing200TextResponse struct { @@ -179,7 +179,9 @@ type GetPing200TextResponse struct { func (response GetPing200TextResponse) VisitGetPingResponse(w http.ResponseWriter) error { w.Header().Set("Content-Type", "text/plain") - w.Header().Set("MyHeader", fmt.Sprint(response.Headers.MyHeader)) + if response.Headers.MyHeader != nil { + w.Header().Set("MyHeader", fmt.Sprint(*response.Headers.MyHeader)) + } w.WriteHeader(200) _, err := w.Write([]byte(response.Body)) diff --git a/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go b/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go index 6eadcef68e..12df040ba4 100644 --- a/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go +++ b/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go @@ -4,7 +4,7 @@ package headdigitofhttpheader type N200ResponseHeaders struct { - N000Foo string + N000Foo *string } type N200Response struct { Headers N200ResponseHeaders diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index 01ef76a0c7..3632359f84 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -1103,8 +1103,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -1121,6 +1123,12 @@ func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(w http w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } w.WriteHeader(200) _, err := buf.WriteTo(w) return err @@ -1775,25 +1783,26 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 9770f43472..067448ae36 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -825,8 +825,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -843,6 +845,12 @@ func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(w http w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } w.WriteHeader(200) _, err := buf.WriteTo(w) return err @@ -1450,25 +1458,26 @@ func (sh *strictHandler) UnionExample(ctx echo.Context) error { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index 2ab5fc04b9..c1b3bd431c 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -942,8 +942,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader string + OptionalHeader string } type HeadersExample200JSONResponse struct { @@ -954,6 +956,8 @@ type HeadersExample200JSONResponse struct { func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(ctx *fiber.Ctx) error { ctx.Response().Header.Set("header1", fmt.Sprint(response.Headers.Header1)) ctx.Response().Header.Set("header2", fmt.Sprint(response.Headers.Header2)) + ctx.Response().Header.Set("nullable-header", fmt.Sprint(response.Headers.NullableHeader)) + ctx.Response().Header.Set("optional-header", fmt.Sprint(response.Headers.OptionalHeader)) ctx.Response().Header.Set("Content-Type", "application/json") ctx.Status(200) @@ -1557,25 +1561,26 @@ func (sh *strictHandler) UnionExample(ctx *fiber.Ctx) error { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 25b3f654db..d854ee3cc7 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -898,8 +898,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -916,6 +918,12 @@ func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(w http w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } w.WriteHeader(200) _, err := buf.WriteTo(w) return err @@ -1573,25 +1581,26 @@ func (sh *strictHandler) UnionExample(ctx *gin.Context) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index c27989b6c4..48846b2438 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -1014,8 +1014,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -1032,6 +1034,12 @@ func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(w http w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } w.WriteHeader(200) _, err := buf.WriteTo(w) return err @@ -1686,25 +1694,26 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 033e1dd769..7d81a25fe5 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -777,8 +777,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader string + OptionalHeader string } type HeadersExample200JSONResponse struct { @@ -789,6 +791,8 @@ type HeadersExample200JSONResponse struct { func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(ctx iris.Context) error { ctx.ResponseWriter().Header().Set("header1", fmt.Sprint(response.Headers.Header1)) ctx.ResponseWriter().Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + ctx.ResponseWriter().Header().Set("nullable-header", fmt.Sprint(response.Headers.NullableHeader)) + ctx.ResponseWriter().Header().Set("optional-header", fmt.Sprint(response.Headers.OptionalHeader)) ctx.ResponseWriter().Header().Set("Content-Type", "application/json") ctx.StatusCode(200) @@ -1459,25 +1463,26 @@ func (sh *strictHandler) UnionExample(ctx iris.Context) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 8eca306a54..21e96956c5 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -1009,8 +1009,10 @@ type HeadersExampleResponseObject interface { } type HeadersExample200ResponseHeaders struct { - Header1 string - Header2 int + Header1 string + Header2 int + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -1027,6 +1029,12 @@ func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(w http w.Header().Set("Content-Type", "application/json") w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) w.Header().Set("header2", fmt.Sprint(response.Headers.Header2)) + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } w.WriteHeader(200) _, err := buf.WriteTo(w) return err @@ -1681,25 +1689,26 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZTXPbNhP+Kzt431NKmrbjE2+NJ5O2aeuObJ86PkDESkJCAiiwFK3R6L93QEBfFq1K", - "qT4ynt5Ecr/wPLuLBTRlha6MVqjIsXzKLDqjlcP2oc+Fxb9qdOSfBLrCSkNSK5azD1z04rdZwizWjvdL", - "nKt7+UIrQtWqcmNKWXCvmn1xXn/KXDHCivtf/7c4YDn7X7YMJQtfXYbPvDIlstlslryI4O4zS9gIuUDb", - "Rht+Xq3bpolBljNHVqoh80aC2HWnmFSEQ7TemxeNQXiBeRz5lBmrDVqSAaMxL2vs9hTf6P4XLCisQKqB", - "3sTyViviUjkQcjBAi4ogggfehgNXG6MtoYD+BLyHgsChHaNlCSNJPjB2v/oeYsCOJWyM1gVHVxeXF5ee", - "L21QcSNZzt63rxJmOI3aBS0IMrqL91/u734H6YDXpCtOsuBlOYGKWzfiJQqQirQPsS7IXbDWk22J/1lE", - "7Y8RSp81bQJ90GJyjIRp83Ilna8vL0+Ul7OE3QRnXTYWQWUrBdaaGfC67MD8UX1VulGA1mobV5ZVdUnS", - "cEurXK2j/dtcZBfIF/aygbZVKjjxI6F+KE/nBj61WHJCsQMBvSC5Hw8r5o/Kwr/xc1YOYj/u7FP3I904", - "GOkGSINAXkIjaQRzxRcNVirg4KQalgjzoJJOMkuM296PSvTiWh68jaP3s2TNynPaNE3aFlBtS1SFFt9G", - "YcJkxYeYGTVcV/e2ObGc9SfkU3ZzgztQISeM8JkyU3Kptu/eJ2rp/yF9sMIO5eofpUWRekbSfqyP7sKN", - "5QVeyg8ac90EnIZKOl+l4aMb6boUwMuGT1zoD5sTRy+q+8mjLcyjjx3BgffJcrI1vu0xZEGtz6zzUPuA", - "z/SP1O6R+PvSd+qa2p+i9kwg0qFOv+Kk0VakhlteIaF12dTHOfO2hthh8o+FJBRcQR9B8QoF8AGhhU8a", - "oknXwU/w+0l/DiJLU+2BY/GQ/zllHrz2EMIS5h2wPOD3ko5kC8BPx6VqjmY46qZrrl5L+Cgyh87iwPmB", - "pIvjDvyCp96KxHmOTNtzc+Pwf4qk9ky+Pnj7lrDLsH3AweN77wJ1ePk6ZlFrF9i+cY7ZAcWxFKizytzs", - "aflsoDqDhRxIFGlcRRpie60l3GpVWKT1A4jfDJUmWBiD/gRohBAQaPfHBqGqHYHhzoGktouUMtwVCdxo", - "Ho/LyG6Dp4dlO93G6rsjcfruXIzeXF7tr/L+yHmzdpB4pR57v34MMvvemB3sxLLneetwfs9Uzo2kUbpy", - "pdxdwj8FgeWeXqAc+4lICbBItVUoYCz5/Bp0ozajgSWtXbNQCGM5Dc2vt/cZiJKttq5Zsu0K/OkNX9Ae", - "84+DU+VpreS2i/pH/xniDP1yb5BafafX8LwktIqTHOMPh7m/2bSiFd4N2kp7wXKyo4ent5dVs4SFf45C", - "C6pt6fsEkcmzLPzjdOEaPhyivZA640Z6FP4OAAD//0nTejA+HAAA", + "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", + "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", + "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", + "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", + "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", + "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", + "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", + "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", + "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", + "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", + "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", + "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", + "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", + "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", + "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", + "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", + "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", + "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", + "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", + "AAD//ysZ4qQMHQAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/strict-schema.yaml b/internal/test/strict-server/strict-schema.yaml index 8b18edd541..ba1a2ffab3 100644 --- a/internal/test/strict-server/strict-schema.yaml +++ b/internal/test/strict-server/strict-schema.yaml @@ -192,11 +192,21 @@ paths: description: OK headers: header1: + required: true schema: type: string header2: + required: true schema: type: integer + optional-header: + required: false + schema: + type: string + nullable-header: + schema: + type: string + nullable: true content: application/json: schema: @@ -320,9 +330,11 @@ paths: description: OK headers: header1: + required: true schema: type: string header2: + required: true schema: type: integer content: @@ -346,9 +358,11 @@ components: description: OK headers: header1: + required: true schema: type: string header2: + required: true schema: type: integer content: diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index d3e67a1b95..abdab8f049 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -287,6 +287,16 @@ type CompatibilityOptions struct { // NOTE that this will not impact generated code. // NOTE that if you're using `include-operation-ids` or `exclude-operation-ids` you may want to ensure that the `operationId`s used are correct. PreserveOriginalOperationIdCasingInEmbeddedSpec bool `yaml:"preserve-original-operation-id-casing-in-embedded-spec"` + + // HeadersImplicitlyRequired treats all response headers as required, ignoring + // the `required` property from the header definition. Prior to v2.6.0, + // oapi-codegen generated all response headers as direct values (implicitly + // required). The OpenAPI specification defaults headers to optional + // (required: false), so the corrected behavior generates optional headers as + // pointers. Set this to true to restore the old behavior where all headers + // are treated as required. + // Please see https://github.com/oapi-codegen/oapi-codegen/issues/2267 + HeadersImplicitlyRequired bool `yaml:"headers-implicitly-required,omitempty"` } func (co CompatibilityOptions) Validate() map[string]string { diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index d9bf1dcbfb..69f8fd9765 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -595,9 +595,43 @@ func (r ResponseContentDefinition) IsJSON() bool { } type ResponseHeaderDefinition struct { - Name string - GoName string - Schema Schema + Name string + GoName string + Schema Schema + Required bool + Nullable bool +} + +// GoTypeDef returns the Go type string for this header, applying pointer or +// nullable wrapping based on the Required/Nullable fields and global config. +func (h ResponseHeaderDefinition) GoTypeDef() string { + typeDef := h.Schema.TypeDecl() + if globalState.options.OutputOptions.NullableType && h.Nullable { + return "nullable.Nullable[" + typeDef + "]" + } + if !h.Schema.SkipOptionalPointer && (!h.Required || h.Nullable) { + typeDef = "*" + typeDef + } + return typeDef +} + +// IsOptional returns true if this header's Go type is indirect (pointer or +// nullable wrapper), meaning the template should guard before calling +// w.Header().Set(). This must stay in sync with GoTypeDef(). +func (h ResponseHeaderDefinition) IsOptional() bool { + if h.IsNullable() { + return true + } + if h.Schema.SkipOptionalPointer { + return false + } + return !h.Required || h.Nullable +} + +// IsNullable returns true if the header type uses nullable.Nullable[T] +// rather than a pointer for optionality. +func (h ResponseHeaderDefinition) IsNullable() bool { + return globalState.options.OutputOptions.NullableType && h.Nullable } // FilterParameterDefinitionByType returns the subset of the specified parameters which are of the @@ -940,7 +974,14 @@ func GenerateResponseDefinitions(operationID string, responses map[string]*opena if err != nil { return nil, fmt.Errorf("error generating response header definition: %w", err) } - headerDefinition := ResponseHeaderDefinition{Name: headerName, GoName: SchemaNameToTypeName(headerName), Schema: contentSchema} + nullable := header.Value.Schema != nil && header.Value.Schema.Value != nil && header.Value.Schema.Value.Nullable + headerDefinition := ResponseHeaderDefinition{ + Name: headerName, + GoName: SchemaNameToTypeName(headerName), + Schema: contentSchema, + Required: header.Value.Required || globalState.options.Compatibility.HeadersImplicitlyRequired, + Nullable: nullable, + } responseHeaderDefinitions = append(responseHeaderDefinitions, headerDefinition) } diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index f6108de7a9..fc1f53ca01 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -32,7 +32,7 @@ {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.Schema.TypeDecl}} + {{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}} @@ -83,7 +83,17 @@ } w.Header().Set("Content-Type", {{if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) {{range $headers -}} - w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + w.Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) _, err := buf.WriteTo(w) @@ -95,7 +105,17 @@ } w.Header().Set("Content-Type", {{if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) {{range $headers -}} - w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + w.Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) _, err = w.Write([]byte(form.Encode())) @@ -108,7 +128,17 @@ } {{end -}} {{range $headers -}} - w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + w.Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) diff --git a/pkg/codegen/templates/strict/strict-responses.tmpl b/pkg/codegen/templates/strict/strict-responses.tmpl index d04cbd7d6c..74f5d96494 100644 --- a/pkg/codegen/templates/strict/strict-responses.tmpl +++ b/pkg/codegen/templates/strict/strict-responses.tmpl @@ -4,7 +4,7 @@ {{if $hasHeaders -}} type {{$name}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.Schema.TypeDecl}} + {{.GoName}} {{.GoTypeDef}} {{end -}} } {{end -}} From 434cc16b427dcc1d63fc3e7e6b9c2f5337418be1 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Thu, 16 Apr 2026 15:36:27 +0100 Subject: [PATCH 31/62] docs: remove non-breaking spaces (#2328) Although they're safe in this case, Renovate's "hidden whitespace" detection is flagging it. As we don't need them, we can remove them. Not-signed-off-by: Jamie Tanna --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aa4dc860ee..bc9b8757e7 100644 --- a/README.md +++ b/README.md @@ -2134,11 +2134,11 @@ To get `oapi-codegen`'s multi-package support working, we need to set up our dir ``` ├── admin -│   ├── cfg.yaml -│   └── generate.go +│ ├── cfg.yaml +│ └── generate.go └── common ├── cfg.yaml -    └── generate.go + └── generate.go ``` We could start with our configuration file for our admin API spec: From c2095464aea566dafda7ff63b66b0f7e4fb51b42 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 20 Apr 2026 06:44:08 -0700 Subject: [PATCH 32/62] fix: clean up and test parameter binding (#2307) * fix: clean up and test parameter binding Audit and fix parameter binding in all 8 server code generation templates (Echo v4, Echo v5, Chi, Gin, Gorilla, Iris, Fiber, stdhttp) to ensure consistent, correct handling of path, query, header, and cookie parameters across all OpenAPI styles and types. Template fixes: - Add missing ParamLocation to path params (Gin, Fiber, Gorilla) and cookie params (Chi, Gin, Fiber, Gorilla, stdhttp) so the runtime applies correct URL escaping per location - Add missing Type/Format fields to Echo v5 path, header, and cookie params, and upgrade its query binding to BindQueryParameterWithOptions - Fix required deepObject query params rejected by a spurious pre-check in Chi, Gin, Gorilla, Fiber, and stdhttp templates - Fix Gin, Iris, and Fiber using query param getters instead of path param getters for content-based (passthrough/JSON) path parameters - Fix Iris cookie params calling nonexistent ctx.Cookie() (now ctx.GetCookie()) and query params calling ctx.QueryParam() (now ctx.URLParam()) - Fix Fiber cookie params redeclaring var in a loop (now block-scoped) - Fix Fiber not URL-decoding path param values for passthrough/JSON - Add _ = err to suppress unused variable when only passthrough path params exist (Chi, Gin, Gorilla, Iris, Fiber, stdhttp) Multi-router parameter roundtrip test: - New test infrastructure under internal/test/parameters/ with per-router subdirectories (echo, chi, gin, gorilla, iris, fiber, stdhttp) plus a shared client package - Each router's server echoes received parameters back as JSON; the shared testImpl sends requests via the generated client and verifies the JSON response matches the original values - Generated files isolated in gen/ subdirectories so go generate works even when generated code has compilation errors - Echo v5 in its own module (Go 1.25+) with version-guarded Makefile - Covers all OpenAPI parameter styles (simple, label, matrix, form, deepObject) x types (primitive, array, object) x explode flags across path, query, header, and cookie locations Skipped tests pending external changes: - spaceDelimited and pipeDelimited query styles: runtime does not yet support binding these styles (oapi-codegen/runtime#116) - stdhttp roundtrip: stdlib ServeMux cannot register path wildcards starting with a digit like {1param} (#2306) Closes: #777, #1752 Obsoletes: #1751, #2062 Co-Authored-By: Claude Opus 4.6 (1M context) * Update runtime and unstub tests Runtime 1.4.0 allows us to run almost all parameter tests. * Update all sub-modules runtime version * run go mod tidy in echo v5 --------- Co-authored-by: Claude Opus 4.6 (1M context) --- examples/go.mod | 2 +- examples/go.sum | 4 +- .../echo-v5/api/petstore-server.gen.go | 8 +- examples/petstore-expanded/echo-v5/go.mod | 4 +- examples/petstore-expanded/echo-v5/go.sum | 8 +- .../stdhttp/api/petstore.gen.go | 18 +- examples/petstore-expanded/stdhttp/go.mod | 4 +- examples/petstore-expanded/stdhttp/go.sum | 8 +- internal/test/cookies/cookies.gen.go | 5 +- internal/test/go.mod | 2 +- internal/test/go.sum | 4 +- .../issue-1378/bionicle/bionicle.gen.go | 3 +- .../issue-1378/fooservice/fooservice.gen.go | 3 +- .../test/issues/issue-2232/issue2232.gen.go | 37 +- .../name_normalizer.gen.go | 3 +- .../name_normalizer.gen.go | 3 +- .../name_normalizer.gen.go | 3 +- .../to-camel-case/name_normalizer.gen.go | 3 +- .../unset/name_normalizer.gen.go | 3 +- .../test/parameters/chi/gen/server.gen.go | 1663 +++++++++ internal/test/parameters/chi/gen/types.gen.go | 143 + internal/test/parameters/chi/server.cfg.yaml | 6 + internal/test/parameters/chi/server.go | 48 + internal/test/parameters/chi/types.cfg.yaml | 5 + .../test/parameters/client/client.cfg.yaml | 6 + internal/test/parameters/client/client.go | 3 + .../gen/client.gen.go} | 1477 ++++---- internal/test/parameters/config.yaml | 8 - internal/test/parameters/doc.go | 3 +- .../test/parameters/echo/gen/server.gen.go | 977 +++++ .../test/parameters/echo/gen/types.gen.go | 143 + .../parameters/{ => echo}/parameters_test.go | 341 +- internal/test/parameters/echo/server.cfg.yaml | 6 + internal/test/parameters/echo/server.go | 44 + internal/test/parameters/echo/types.cfg.yaml | 5 + internal/test/parameters/echov5/Makefile | 45 + .../test/parameters/echov5/client.cfg.yaml | 5 + internal/test/parameters/echov5/client.gen.go | 3162 +++++++++++++++++ .../parameters/echov5/echov5_param_test.go | 381 ++ internal/test/parameters/echov5/go.mod | 41 + internal/test/parameters/echov5/go.sum | 190 + .../test/parameters/echov5/server.cfg.yaml | 6 + internal/test/parameters/echov5/server.gen.go | 977 +++++ internal/test/parameters/echov5/server.go | 41 + .../test/parameters/echov5/types.cfg.yaml | 5 + internal/test/parameters/echov5/types.gen.go | 143 + .../test/parameters/fiber/gen/server.gen.go | 1430 ++++++++ .../test/parameters/fiber/gen/types.gen.go | 143 + .../test/parameters/fiber/server.cfg.yaml | 6 + internal/test/parameters/fiber/server.go | 44 + internal/test/parameters/fiber/types.cfg.yaml | 5 + .../test/parameters/gin/gen/server.gen.go | 1293 +++++++ internal/test/parameters/gin/gen/types.gen.go | 143 + internal/test/parameters/gin/server.cfg.yaml | 6 + internal/test/parameters/gin/server.go | 44 + internal/test/parameters/gin/types.cfg.yaml | 5 + .../test/parameters/gorilla/gen/server.gen.go | 1496 ++++++++ .../test/parameters/gorilla/gen/types.gen.go | 143 + .../test/parameters/gorilla/server.cfg.yaml | 6 + internal/test/parameters/gorilla/server.go | 48 + .../test/parameters/gorilla/types.cfg.yaml | 5 + .../test/parameters/iris/gen/server.gen.go | 1132 ++++++ .../test/parameters/iris/gen/types.gen.go | 143 + internal/test/parameters/iris/server.cfg.yaml | 6 + internal/test/parameters/iris/server.go | 44 + internal/test/parameters/iris/types.cfg.yaml | 5 + .../test/parameters/param_roundtrip_test.go | 517 +++ internal/test/parameters/parameters.yaml | 104 + .../test/parameters/stdhttp/gen/server.gen.go | 1478 ++++++++ .../test/parameters/stdhttp/gen/types.gen.go | 143 + .../test/parameters/stdhttp/server.cfg.yaml | 6 + internal/test/parameters/stdhttp/server.go | 48 + .../test/parameters/stdhttp/types.cfg.yaml | 5 + internal/test/server/server.gen.go | 35 +- internal/test/strict-server/chi/server.gen.go | 2 + .../test/strict-server/fiber/server.gen.go | 4 +- internal/test/strict-server/gin/server.gen.go | 4 +- .../test/strict-server/gorilla/server.gen.go | 4 +- .../test/strict-server/iris/server.gen.go | 2 + internal/test/strict-server/stdhttp/go.mod | 2 +- internal/test/strict-server/stdhttp/go.sum | 4 +- .../test/strict-server/stdhttp/server.gen.go | 2 + pkg/codegen/templates/chi/chi-middleware.tmpl | 12 +- .../templates/echo/v5/echo-wrappers.tmpl | 8 +- .../templates/fiber/fiber-middleware.tmpl | 30 +- pkg/codegen/templates/gin/gin-wrappers.tmpl | 11 +- .../templates/gorilla/gorilla-middleware.tmpl | 14 +- .../templates/iris/iris-middleware.tmpl | 15 +- .../stdhttp/std-http-middleware.tmpl | 12 +- 89 files changed, 17426 insertions(+), 1182 deletions(-) create mode 100644 internal/test/parameters/chi/gen/server.gen.go create mode 100644 internal/test/parameters/chi/gen/types.gen.go create mode 100644 internal/test/parameters/chi/server.cfg.yaml create mode 100644 internal/test/parameters/chi/server.go create mode 100644 internal/test/parameters/chi/types.cfg.yaml create mode 100644 internal/test/parameters/client/client.cfg.yaml create mode 100644 internal/test/parameters/client/client.go rename internal/test/parameters/{parameters.gen.go => client/gen/client.gen.go} (69%) delete mode 100644 internal/test/parameters/config.yaml create mode 100644 internal/test/parameters/echo/gen/server.gen.go create mode 100644 internal/test/parameters/echo/gen/types.gen.go rename internal/test/parameters/{ => echo}/parameters_test.go (71%) create mode 100644 internal/test/parameters/echo/server.cfg.yaml create mode 100644 internal/test/parameters/echo/server.go create mode 100644 internal/test/parameters/echo/types.cfg.yaml create mode 100644 internal/test/parameters/echov5/Makefile create mode 100644 internal/test/parameters/echov5/client.cfg.yaml create mode 100644 internal/test/parameters/echov5/client.gen.go create mode 100644 internal/test/parameters/echov5/echov5_param_test.go create mode 100644 internal/test/parameters/echov5/go.mod create mode 100644 internal/test/parameters/echov5/go.sum create mode 100644 internal/test/parameters/echov5/server.cfg.yaml create mode 100644 internal/test/parameters/echov5/server.gen.go create mode 100644 internal/test/parameters/echov5/server.go create mode 100644 internal/test/parameters/echov5/types.cfg.yaml create mode 100644 internal/test/parameters/echov5/types.gen.go create mode 100644 internal/test/parameters/fiber/gen/server.gen.go create mode 100644 internal/test/parameters/fiber/gen/types.gen.go create mode 100644 internal/test/parameters/fiber/server.cfg.yaml create mode 100644 internal/test/parameters/fiber/server.go create mode 100644 internal/test/parameters/fiber/types.cfg.yaml create mode 100644 internal/test/parameters/gin/gen/server.gen.go create mode 100644 internal/test/parameters/gin/gen/types.gen.go create mode 100644 internal/test/parameters/gin/server.cfg.yaml create mode 100644 internal/test/parameters/gin/server.go create mode 100644 internal/test/parameters/gin/types.cfg.yaml create mode 100644 internal/test/parameters/gorilla/gen/server.gen.go create mode 100644 internal/test/parameters/gorilla/gen/types.gen.go create mode 100644 internal/test/parameters/gorilla/server.cfg.yaml create mode 100644 internal/test/parameters/gorilla/server.go create mode 100644 internal/test/parameters/gorilla/types.cfg.yaml create mode 100644 internal/test/parameters/iris/gen/server.gen.go create mode 100644 internal/test/parameters/iris/gen/types.gen.go create mode 100644 internal/test/parameters/iris/server.cfg.yaml create mode 100644 internal/test/parameters/iris/server.go create mode 100644 internal/test/parameters/iris/types.cfg.yaml create mode 100644 internal/test/parameters/param_roundtrip_test.go create mode 100644 internal/test/parameters/stdhttp/gen/server.gen.go create mode 100644 internal/test/parameters/stdhttp/gen/types.gen.go create mode 100644 internal/test/parameters/stdhttp/server.cfg.yaml create mode 100644 internal/test/parameters/stdhttp/server.go create mode 100644 internal/test/parameters/stdhttp/types.cfg.yaml diff --git a/examples/go.mod b/examples/go.mod index bb3606ee88..f0833793ce 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -20,7 +20,7 @@ require ( github.com/oapi-codegen/iris-middleware v1.0.5 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 golang.org/x/lint v0.0.0-20241112194109-818c5a804067 diff --git a/examples/go.sum b/examples/go.sum index 290007b754..5777a31fe3 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -206,8 +206,8 @@ github.com/oapi-codegen/iris-middleware v1.0.5 h1:eO33pCvapaf1Xa0esEP0PYcdqPZSeq github.com/oapi-codegen/iris-middleware v1.0.5/go.mod h1:/ysgvbjWyhfDAouIeUOjzIv+zsXfaIXlAQrsOU9/Kyo= github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe513tvJpiMJjypVPA= github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= diff --git a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go index c99d14e424..ac4b6f5270 100644 --- a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go +++ b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go @@ -48,14 +48,14 @@ func (w *ServerInterfaceWrapper) FindPets(ctx *echo.Context) error { var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", ctx.QueryParams(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", ctx.QueryParams(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tags: %s", err)) } // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err)) } @@ -80,7 +80,7 @@ func (w *ServerInterfaceWrapper) DeletePet(ctx *echo.Context) error { // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) } @@ -96,7 +96,7 @@ func (w *ServerInterfaceWrapper) FindPetByID(ctx *echo.Context) error { // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) } diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod index 6e9281b491..3a9a5d3ef9 100644 --- a/examples/petstore-expanded/echo-v5/go.mod +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -8,7 +8,7 @@ require ( github.com/getkin/kin-openapi v0.135.0 github.com/labstack/echo/v5 v5.0.4 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) @@ -19,7 +19,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum index 824267217c..a653a1f09f 100644 --- a/examples/petstore-expanded/echo-v5/go.sum +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -42,8 +42,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -67,8 +67,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= diff --git a/examples/petstore-expanded/stdhttp/api/petstore.gen.go b/examples/petstore-expanded/stdhttp/api/petstore.gen.go index 74019839df..aa60a0891e 100644 --- a/examples/petstore-expanded/stdhttp/api/petstore.gen.go +++ b/examples/petstore-expanded/stdhttp/api/petstore.gen.go @@ -9,6 +9,7 @@ import ( "bytes" "compress/gzip" "encoding/base64" + "errors" "fmt" "net/http" "net/url" @@ -90,6 +91,7 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams @@ -98,7 +100,12 @@ func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Reque err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", r.URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "tags"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + } return } @@ -106,7 +113,12 @@ func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Reque err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", r.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "limit"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + } return } @@ -139,6 +151,7 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 @@ -164,6 +177,7 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index ed943eb926..0a642f935f 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -8,7 +8,7 @@ require ( github.com/getkin/kin-openapi v0.135.0 github.com/oapi-codegen/nethttp-middleware v1.1.2 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.2.0 + github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) @@ -19,7 +19,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.1 // indirect diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index a3cede0861..b5ae3a9f9f 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -42,8 +42,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -67,8 +67,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/nethttp-middleware v1.1.2 h1:TQwEU3WM6ifc7ObBEtiJgbRPaCe513tvJpiMJjypVPA= github.com/oapi-codegen/nethttp-middleware v1.1.2/go.mod h1:5qzjxMSiI8HjLljiOEjvs4RdrWyMPKnExeFS2kr8om4= -github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= -github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= diff --git a/internal/test/cookies/cookies.gen.go b/internal/test/cookies/cookies.gen.go index 4e9b6139ec..1efbec0cdf 100644 --- a/internal/test/cookies/cookies.gen.go +++ b/internal/test/cookies/cookies.gen.go @@ -49,6 +49,7 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) CookieParams(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params CookieParamsParams @@ -58,7 +59,7 @@ func (siw *ServerInterfaceWrapper) CookieParams(w http.ResponseWriter, r *http.R if cookie, err = r.Cookie("authId"); err == nil { var value string - err = runtime.BindStyledParameterWithOptions("simple", "authId", cookie.Value, &value, runtime.BindStyledParameterOptions{Explode: true, Required: false, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "authId", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "authId", Err: err}) return @@ -73,7 +74,7 @@ func (siw *ServerInterfaceWrapper) CookieParams(w http.ResponseWriter, r *http.R if cookie, err = r.Cookie("serverId"); err == nil { var value string - err = runtime.BindStyledParameterWithOptions("simple", "serverId", cookie.Value, &value, runtime.BindStyledParameterOptions{Explode: true, Required: false, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "serverId", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "serverId", Err: err}) return diff --git a/internal/test/go.mod b/internal/test/go.mod index c7ead48dc0..88b0357176 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -15,7 +15,7 @@ require ( github.com/labstack/echo/v4 v4.15.1 github.com/oapi-codegen/nullable v1.1.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.3.1 + github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v2 v2.4.0 diff --git a/internal/test/go.sum b/internal/test/go.sum index 2a53255d80..969bd3f82f 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -182,8 +182,8 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= -github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+5xB9g= -github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index c18418eaef..ad3c48fb16 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -50,11 +50,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetBionicleName(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "name" ------------- var name BionicleName - err = runtime.BindStyledParameterWithOptions("simple", "name", mux.Vars(r)["name"], &name, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "name", mux.Vars(r)["name"], &name, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "name", Err: err}) return diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index 966de191e5..cf32c3e258 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -43,11 +43,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetBionicleName(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "name" ------------- var name externalRef0.BionicleName - err = runtime.BindStyledParameterWithOptions("simple", "name", mux.Vars(r)["name"], &name, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "name", mux.Vars(r)["name"], &name, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "name", Err: err}) return diff --git a/internal/test/issues/issue-2232/issue2232.gen.go b/internal/test/issues/issue-2232/issue2232.gen.go index b99598ba4f..a63393b342 100644 --- a/internal/test/issues/issue-2232/issue2232.gen.go +++ b/internal/test/issues/issue-2232/issue2232.gen.go @@ -6,6 +6,7 @@ package issue2232 import ( + "errors" "fmt" "net/http" @@ -81,37 +82,34 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetEndpoint(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params GetEndpointParams // ------------- Required query parameter "env_param_level" ------------- - if paramValue := r.URL.Query().Get("env_param_level"); paramValue != "" { - - } else { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "env_param_level"}) - return - } - err = runtime.BindQueryParameterWithOptions("form", true, true, "env_param_level", r.URL.Query(), ¶ms.EnvParamLevel, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "env_param_level", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "env_param_level"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "env_param_level", Err: err}) + } return } // ------------- Required query parameter "env_schema_level" ------------- - if paramValue := r.URL.Query().Get("env_schema_level"); paramValue != "" { - - } else { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "env_schema_level"}) - return - } - err = runtime.BindQueryParameterWithOptions("form", true, true, "env_schema_level", r.URL.Query(), ¶ms.EnvSchemaLevel, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "env_schema_level", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "env_schema_level"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "env_schema_level", Err: err}) + } return } @@ -119,7 +117,12 @@ func (siw *ServerInterfaceWrapper) GetEndpoint(w http.ResponseWriter, r *http.Re err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", r.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "limit"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + } return } diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go index 0b00613664..cbd8ff259e 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go @@ -364,11 +364,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetHTTPPet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "petId" ------------- var petID string - err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petID, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "petId", Err: err}) return diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go index 93dc41ff9b..19d2761adc 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go @@ -364,11 +364,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetHttpPet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "petId" ------------- var petId string - err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "petId", Err: err}) return diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go index 935b805c1c..ae310f8f39 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go @@ -364,11 +364,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetHTTPPet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "petId" ------------- var petID string - err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petID, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "petId", Err: err}) return diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go index 50478990af..a8696bf99d 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go @@ -364,11 +364,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetHttpPet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "petId" ------------- var petId string - err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "petId", Err: err}) return diff --git a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go index 59d306d519..ca724a735b 100644 --- a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go @@ -364,11 +364,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetHttpPet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "petId" ------------- var petId string - err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "petId", mux.Vars(r)["petId"], &petId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "petId", Err: err}) return diff --git a/internal/test/parameters/chi/gen/server.gen.go b/internal/test/parameters/chi/gen/server.gen.go new file mode 100644 index 0000000000..e191f7959c --- /dev/null +++ b/internal/test/parameters/chi/gen/server.gen.go @@ -0,0 +1,1663 @@ +// Package chiparamsgen 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 chiparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/go-chi/chi/v5" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(w http.ResponseWriter, r *http.Request, param ComplexObject) + + // (GET /cookie) + GetCookie(w http.ResponseWriter, r *http.Request, params GetCookieParams) + + // (GET /enums) + EnumParams(w http.ResponseWriter, r *http.Request, params EnumParamsParams) + + // (GET /header) + GetHeader(w http.ResponseWriter, r *http.Request, params GetHeaderParams) + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /passThrough/{param}) + GetPassThrough(w http.ResponseWriter, r *http.Request, param string) + + // (GET /queryDeepObject) + GetDeepObject(w http.ResponseWriter, r *http.Request, params GetDeepObjectParams) + + // (GET /queryDelimited) + GetQueryDelimited(w http.ResponseWriter, r *http.Request, params GetQueryDelimitedParams) + + // (GET /queryForm) + GetQueryForm(w http.ResponseWriter, r *http.Request, params GetQueryFormParams) + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// (GET /contentObject/{param}) +func (_ Unimplemented) GetContentObject(w http.ResponseWriter, r *http.Request, param ComplexObject) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /cookie) +func (_ Unimplemented) GetCookie(w http.ResponseWriter, r *http.Request, params GetCookieParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /enums) +func (_ Unimplemented) EnumParams(w http.ResponseWriter, r *http.Request, params EnumParamsParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /header) +func (_ Unimplemented) GetHeader(w http.ResponseWriter, r *http.Request, params GetHeaderParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelExplodeArray/{.param*}) +func (_ Unimplemented) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelExplodeObject/{.param*}) +func (_ Unimplemented) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelExplodePrimitive/{.param*}) +func (_ Unimplemented) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelNoExplodeArray/{.param}) +func (_ Unimplemented) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelNoExplodeObject/{.param}) +func (_ Unimplemented) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /labelPrimitive/{.param}) +func (_ Unimplemented) GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixExplodeArray/{.id*}) +func (_ Unimplemented) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixExplodeObject/{.id*}) +func (_ Unimplemented) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixExplodePrimitive/{;id*}) +func (_ Unimplemented) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixNoExplodeArray/{.id}) +func (_ Unimplemented) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixNoExplodeObject/{.id}) +func (_ Unimplemented) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /matrixPrimitive/{;id}) +func (_ Unimplemented) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /passThrough/{param}) +func (_ Unimplemented) GetPassThrough(w http.ResponseWriter, r *http.Request, param string) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /queryDeepObject) +func (_ Unimplemented) GetDeepObject(w http.ResponseWriter, r *http.Request, params GetDeepObjectParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /queryDelimited) +func (_ Unimplemented) GetQueryDelimited(w http.ResponseWriter, r *http.Request, params GetQueryDelimitedParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /queryForm) +func (_ Unimplemented) GetQueryForm(w http.ResponseWriter, r *http.Request, params GetQueryFormParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simpleExplodeArray/{param*}) +func (_ Unimplemented) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simpleExplodeObject/{param*}) +func (_ Unimplemented) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simpleExplodePrimitive/{param}) +func (_ Unimplemented) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simpleNoExplodeArray/{param}) +func (_ Unimplemented) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simpleNoExplodeObject/{param}) +func (_ Unimplemented) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /simplePrimitive/{param}) +func (_ Unimplemented) GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /startingWithNumber/{1param}) +func (_ Unimplemented) GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) { + w.WriteHeader(http.StatusNotImplemented) +} + +// 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 + +// GetContentObject operation middleware +func (siw *ServerInterfaceWrapper) GetContentObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(chi.URLParam(r, "param")), ¶m) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetContentObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetCookie operation middleware +func (siw *ServerInterfaceWrapper) GetCookie(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("p"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + return + } + params.P = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ep"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + return + } + params.Ep = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ea"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + return + } + params.Ea = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("a"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + return + } + params.A = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("eo"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + return + } + params.Eo = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("o"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + return + } + params.O = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("co"); err == nil { + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + err = fmt.Errorf("Error unescaping cookie parameter 'co'") + siw.ErrorHandlerFunc(w, r, &UnescapedCookieParamError{ParamName: "co", Err: err}) + return + } + + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("1s"); err == nil { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + return + } + params.N1s = &value + + } + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetCookie(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// EnumParams operation middleware +func (siw *ServerInterfaceWrapper) EnumParams(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", r.URL.Query(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "enumPathParam"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "enumPathParam", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.EnumParams(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetHeader operation middleware +func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := r.Header + + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive", Err: err}) + return + } + + params.XPrimitive = &XPrimitive + + } + + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive-Exploded", Err: err}) + return + } + + params.XPrimitiveExploded = &XPrimitiveExploded + + } + + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array-Exploded", Err: err}) + return + } + + params.XArrayExploded = &XArrayExploded + + } + + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array", Err: err}) + return + } + + params.XArray = &XArray + + } + + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object-Exploded", Err: err}) + return + } + + params.XObjectExploded = &XObjectExploded + + } + + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object", Err: err}) + return + } + + params.XObject = &XObject + + } + + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Complex-Object", Count: n}) + return + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "X-Complex-Object", Err: err}) + return + } + + params.XComplexObject = &XComplexObject + + } + + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "1-Starting-With-Number", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1-Starting-With-Number", Err: err}) + return + } + + params.N1StartingWithNumber = &N1StartingWithNumber + + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetHeader(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelPrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodePrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixPrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetPassThrough operation middleware +func (siw *ServerInterfaceWrapper) GetPassThrough(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param = chi.URLParam(r, "param") + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetPassThrough(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeepObject operation middleware +func (siw *ServerInterfaceWrapper) GetDeepObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", r.URL.Query(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "deepObj"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "deepObj", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeepObject(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryDelimited operation middleware +func (siw *ServerInterfaceWrapper) GetQueryDelimited(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", r.URL.Query(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "sa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "sa", Err: err}) + } + return + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", r.URL.Query(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "pa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "pa", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryDelimited(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryForm operation middleware +func (siw *ServerInterfaceWrapper) GetQueryForm(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", r.URL.Query(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ea"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + } + return + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", r.URL.Query(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "a"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + } + return + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", r.URL.Query(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "eo"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + } + return + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", r.URL.Query(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "o"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + } + return + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", r.URL.Query(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ep"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + } + return + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", r.URL.Query(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "p"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + } + return + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", r.URL.Query(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ps"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ps", Err: err}) + } + return + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := r.URL.Query().Get("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", r.URL.Query(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "1s"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryForm(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimplePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimplePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", chi.URLParam(r, "param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimplePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetStartingWithNumber operation middleware +func (siw *ServerInterfaceWrapper) GetStartingWithNumber(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = chi.URLParam(r, "1param") + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetStartingWithNumber(w, r, n1param) + })) + + 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, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + 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, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + 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, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/contentObject/{param}", wrapper.GetContentObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/cookie", wrapper.GetCookie) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/enums", wrapper.EnumParams) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/header", wrapper.GetHeader) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelExplodeArray/{param}", wrapper.GetLabelExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelExplodeObject/{param}", wrapper.GetLabelExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelExplodePrimitive/{param}", wrapper.GetLabelExplodePrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelNoExplodeArray/{param}", wrapper.GetLabelNoExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelNoExplodeObject/{param}", wrapper.GetLabelNoExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/labelPrimitive/{param}", wrapper.GetLabelPrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixExplodeArray/{id}", wrapper.GetMatrixExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixExplodeObject/{id}", wrapper.GetMatrixExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixExplodePrimitive/{id}", wrapper.GetMatrixExplodePrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixNoExplodeArray/{id}", wrapper.GetMatrixNoExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixNoExplodeObject/{id}", wrapper.GetMatrixNoExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/matrixPrimitive/{id}", wrapper.GetMatrixPrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/passThrough/{param}", wrapper.GetPassThrough) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/queryForm", wrapper.GetQueryForm) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simpleExplodeArray/{param}", wrapper.GetSimpleExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simpleExplodeObject/{param}", wrapper.GetSimpleExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simpleExplodePrimitive/{param}", wrapper.GetSimpleExplodePrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simpleNoExplodeArray/{param}", wrapper.GetSimpleNoExplodeArray) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simpleNoExplodeObject/{param}", wrapper.GetSimpleNoExplodeObject) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/simplePrimitive/{param}", wrapper.GetSimplePrimitive) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/startingWithNumber/{1param}", wrapper.GetStartingWithNumber) + }) + + return r +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/chi/gen/types.gen.go b/internal/test/parameters/chi/gen/types.gen.go new file mode 100644 index 0000000000..cf9e959422 --- /dev/null +++ b/internal/test/parameters/chi/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package chiparamsgen 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 chiparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/chi/server.cfg.yaml b/internal/test/parameters/chi/server.cfg.yaml new file mode 100644 index 0000000000..8347eb6a63 --- /dev/null +++ b/internal/test/parameters/chi/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: chiparamsgen +generate: + chi-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/chi/server.go b/internal/test/parameters/chi/server.go new file mode 100644 index 0000000000..407710288c --- /dev/null +++ b/internal/test/parameters/chi/server.go @@ -0,0 +1,48 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package chiparams + +import ( + "encoding/json" + "net/http" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/chi/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func writeJSON(w http.ResponseWriter, v interface{}) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(v) +} + +func (s *Server) GetContentObject(w http.ResponseWriter, r *http.Request, param gen.ComplexObject) { writeJSON(w, param) } +func (s *Server) GetCookie(w http.ResponseWriter, r *http.Request, params gen.GetCookieParams) { writeJSON(w, params) } +func (s *Server) EnumParams(w http.ResponseWriter, r *http.Request, params gen.EnumParamsParams) { w.WriteHeader(http.StatusNoContent) } +func (s *Server) GetHeader(w http.ResponseWriter, r *http.Request, params gen.GetHeaderParams) { writeJSON(w, params) } +func (s *Server) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetPassThrough(w http.ResponseWriter, r *http.Request, param string) { writeJSON(w, param) } +func (s *Server) GetDeepObject(w http.ResponseWriter, r *http.Request, params gen.GetDeepObjectParams) { writeJSON(w, params) } +func (s *Server) GetQueryDelimited(w http.ResponseWriter, r *http.Request, params gen.GetQueryDelimitedParams) { writeJSON(w, params) } +func (s *Server) GetQueryForm(w http.ResponseWriter, r *http.Request, params gen.GetQueryFormParams) { writeJSON(w, params) } +func (s *Server) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) { writeJSON(w, n1param) } diff --git a/internal/test/parameters/chi/types.cfg.yaml b/internal/test/parameters/chi/types.cfg.yaml new file mode 100644 index 0000000000..c95e41dd59 --- /dev/null +++ b/internal/test/parameters/chi/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: chiparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/client/client.cfg.yaml b/internal/test/parameters/client/client.cfg.yaml new file mode 100644 index 0000000000..7ec6902198 --- /dev/null +++ b/internal/test/parameters/client/client.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: paramclientgen +generate: + client: true + models: true +output: gen/client.gen.go diff --git a/internal/test/parameters/client/client.go b/internal/test/parameters/client/client.go new file mode 100644 index 0000000000..b23b4dc07c --- /dev/null +++ b/internal/test/parameters/client/client.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=client.cfg.yaml ../parameters.yaml + +package paramclient diff --git a/internal/test/parameters/parameters.gen.go b/internal/test/parameters/client/gen/client.gen.go similarity index 69% rename from internal/test/parameters/parameters.gen.go rename to internal/test/parameters/client/gen/client.gen.go index 9a66132841..3da4e16cf9 100644 --- a/internal/test/parameters/parameters.gen.go +++ b/internal/test/parameters/client/gen/client.gen.go @@ -1,23 +1,17 @@ -// Package parameters provides primitives to interact with the openapi HTTP API. +// Package paramclientgen 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 parameters +package paramclientgen import ( - "bytes" - "compress/gzip" "context" - "encoding/base64" "encoding/json" "fmt" "io" "net/http" "net/url" - "path" "strings" - "github.com/getkin/kin-openapi/openapi3" - "github.com/labstack/echo/v4" "github.com/oapi-codegen/runtime" ) @@ -121,6 +115,15 @@ type GetDeepObjectParams struct { DeepObj ComplexObject `json:"deepObj"` } +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + // GetQueryFormParams defines parameters for GetQueryForm. type GetQueryFormParams struct { // Ea exploded array @@ -242,30 +245,45 @@ type ClientInterface interface { // GetLabelExplodeObject request GetLabelExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetLabelExplodePrimitive request + GetLabelExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetLabelNoExplodeArray request GetLabelNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) // GetLabelNoExplodeObject request GetLabelNoExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetLabelPrimitive request + GetLabelPrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetMatrixExplodeArray request GetMatrixExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) // GetMatrixExplodeObject request GetMatrixExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetMatrixExplodePrimitive request + GetMatrixExplodePrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetMatrixNoExplodeArray request GetMatrixNoExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) // GetMatrixNoExplodeObject request GetMatrixNoExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetMatrixPrimitive request + GetMatrixPrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetPassThrough request GetPassThrough(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*http.Response, error) // GetDeepObject request GetDeepObject(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetQueryDelimited request + GetQueryDelimited(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetQueryForm request GetQueryForm(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -275,6 +293,9 @@ type ClientInterface interface { // GetSimpleExplodeObject request GetSimpleExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetSimpleExplodePrimitive request + GetSimpleExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetSimpleNoExplodeArray request GetSimpleNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -360,6 +381,18 @@ func (c *Client) GetLabelExplodeObject(ctx context.Context, param Object, reqEdi return c.Client.Do(req) } +func (c *Client) GetLabelExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelExplodePrimitiveRequest(c.Server, param) + 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 *Client) GetLabelNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetLabelNoExplodeArrayRequest(c.Server, param) if err != nil { @@ -384,6 +417,18 @@ func (c *Client) GetLabelNoExplodeObject(ctx context.Context, param Object, reqE return c.Client.Do(req) } +func (c *Client) GetLabelPrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelPrimitiveRequest(c.Server, param) + 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 *Client) GetMatrixExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetMatrixExplodeArrayRequest(c.Server, id) if err != nil { @@ -408,6 +453,18 @@ func (c *Client) GetMatrixExplodeObject(ctx context.Context, id Object, reqEdito return c.Client.Do(req) } +func (c *Client) GetMatrixExplodePrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixExplodePrimitiveRequest(c.Server, id) + 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 *Client) GetMatrixNoExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetMatrixNoExplodeArrayRequest(c.Server, id) if err != nil { @@ -432,6 +489,18 @@ func (c *Client) GetMatrixNoExplodeObject(ctx context.Context, id Object, reqEdi return c.Client.Do(req) } +func (c *Client) GetMatrixPrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixPrimitiveRequest(c.Server, id) + 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 *Client) GetPassThrough(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetPassThroughRequest(c.Server, param) if err != nil { @@ -456,6 +525,18 @@ func (c *Client) GetDeepObject(ctx context.Context, params *GetDeepObjectParams, return c.Client.Do(req) } +func (c *Client) GetQueryDelimited(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetQueryDelimitedRequest(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 *Client) GetQueryForm(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetQueryFormRequest(c.Server, params) if err != nil { @@ -492,6 +573,18 @@ func (c *Client) GetSimpleExplodeObject(ctx context.Context, param Object, reqEd return c.Client.Do(req) } +func (c *Client) GetSimpleExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleExplodePrimitiveRequest(c.Server, param) + 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 *Client) GetSimpleNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetSimpleNoExplodeArrayRequest(c.Server, param) if err != nil { @@ -970,6 +1063,40 @@ func NewGetLabelExplodeObjectRequest(server string, param Object) (*http.Request return req, nil } +// NewGetLabelExplodePrimitiveRequest generates requests for GetLabelExplodePrimitive +func NewGetLabelExplodePrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelExplodePrimitive/%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 + } + + return req, nil +} + // NewGetLabelNoExplodeArrayRequest generates requests for GetLabelNoExplodeArray func NewGetLabelNoExplodeArrayRequest(server string, param []int32) (*http.Request, error) { var err error @@ -1038,6 +1165,40 @@ func NewGetLabelNoExplodeObjectRequest(server string, param Object) (*http.Reque return req, nil } +// NewGetLabelPrimitiveRequest generates requests for GetLabelPrimitive +func NewGetLabelPrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelPrimitive/%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 + } + + return req, nil +} + // NewGetMatrixExplodeArrayRequest generates requests for GetMatrixExplodeArray func NewGetMatrixExplodeArrayRequest(server string, id []int32) (*http.Request, error) { var err error @@ -1106,6 +1267,40 @@ func NewGetMatrixExplodeObjectRequest(server string, id Object) (*http.Request, return req, nil } +// NewGetMatrixExplodePrimitiveRequest generates requests for GetMatrixExplodePrimitive +func NewGetMatrixExplodePrimitiveRequest(server string, id int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", true, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixExplodePrimitive/%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 + } + + return req, nil +} + // NewGetMatrixNoExplodeArrayRequest generates requests for GetMatrixNoExplodeArray func NewGetMatrixNoExplodeArrayRequest(server string, id []int32) (*http.Request, error) { var err error @@ -1174,6 +1369,40 @@ func NewGetMatrixNoExplodeObjectRequest(server string, id Object) (*http.Request return req, nil } +// NewGetMatrixPrimitiveRequest generates requests for GetMatrixPrimitive +func NewGetMatrixPrimitiveRequest(server string, id int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixPrimitive/%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 + } + + return req, nil +} + // NewGetPassThroughRequest generates requests for GetPassThrough func NewGetPassThroughRequest(server string, param string) (*http.Request, error) { var err error @@ -1255,6 +1484,72 @@ func NewGetDeepObjectRequest(server string, params *GetDeepObjectParams) (*http. return req, nil } +// NewGetQueryDelimitedRequest generates requests for GetQueryDelimited +func NewGetQueryDelimitedRequest(server string, params *GetQueryDelimitedParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/queryDelimited") + 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.Sa != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("spaceDelimited", false, "sa", *params.Sa, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Pa != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("pipeDelimited", false, "pa", *params.Pa, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", 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 +} + // NewGetQueryFormRequest generates requests for GetQueryForm func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Request, error) { var err error @@ -1471,13 +1766,13 @@ func NewGetSimpleExplodeObjectRequest(server string, param Object) (*http.Reques return req, nil } -// NewGetSimpleNoExplodeArrayRequest generates requests for GetSimpleNoExplodeArray -func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Request, error) { +// NewGetSimpleExplodePrimitiveRequest generates requests for GetSimpleExplodePrimitive +func NewGetSimpleExplodePrimitiveRequest(server string, param int32) (*http.Request, error) { var err error var pathParam0 string - pathParam0, err = runtime.StyleParamWithOptions("simple", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + pathParam0, err = runtime.StyleParamWithOptions("simple", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) if err != nil { return nil, err } @@ -1487,7 +1782,7 @@ func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Requ return nil, err } - operationPath := fmt.Sprintf("/simpleNoExplodeArray/%s", pathParam0) + operationPath := fmt.Sprintf("/simpleExplodePrimitive/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1505,8 +1800,42 @@ func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Requ return req, nil } -// NewGetSimpleNoExplodeObjectRequest generates requests for GetSimpleNoExplodeObject -func NewGetSimpleNoExplodeObjectRequest(server string, param Object) (*http.Request, error) { +// NewGetSimpleNoExplodeArrayRequest generates requests for GetSimpleNoExplodeArray +func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleNoExplodeArray/%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 + } + + return req, nil +} + +// NewGetSimpleNoExplodeObjectRequest generates requests for GetSimpleNoExplodeObject +func NewGetSimpleNoExplodeObjectRequest(server string, param Object) (*http.Request, error) { var err error var pathParam0 string @@ -1665,30 +1994,45 @@ type ClientWithResponsesInterface interface { // GetLabelExplodeObjectWithResponse request GetLabelExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelExplodeObjectResponse, error) + // GetLabelExplodePrimitiveWithResponse request + GetLabelExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelExplodePrimitiveResponse, error) + // GetLabelNoExplodeArrayWithResponse request GetLabelNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeArrayResponse, error) // GetLabelNoExplodeObjectWithResponse request GetLabelNoExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeObjectResponse, error) + // GetLabelPrimitiveWithResponse request + GetLabelPrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelPrimitiveResponse, error) + // GetMatrixExplodeArrayWithResponse request GetMatrixExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodeArrayResponse, error) // GetMatrixExplodeObjectWithResponse request GetMatrixExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixExplodeObjectResponse, error) + // GetMatrixExplodePrimitiveWithResponse request + GetMatrixExplodePrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodePrimitiveResponse, error) + // GetMatrixNoExplodeArrayWithResponse request GetMatrixNoExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeArrayResponse, error) // GetMatrixNoExplodeObjectWithResponse request GetMatrixNoExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeObjectResponse, error) + // GetMatrixPrimitiveWithResponse request + GetMatrixPrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixPrimitiveResponse, error) + // GetPassThroughWithResponse request GetPassThroughWithResponse(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*GetPassThroughResponse, error) // GetDeepObjectWithResponse request GetDeepObjectWithResponse(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*GetDeepObjectResponse, error) + // GetQueryDelimitedWithResponse request + GetQueryDelimitedWithResponse(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*GetQueryDelimitedResponse, error) + // GetQueryFormWithResponse request GetQueryFormWithResponse(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*GetQueryFormResponse, error) @@ -1698,6 +2042,9 @@ type ClientWithResponsesInterface interface { // GetSimpleExplodeObjectWithResponse request GetSimpleExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetSimpleExplodeObjectResponse, error) + // GetSimpleExplodePrimitiveWithResponse request + GetSimpleExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodePrimitiveResponse, error) + // GetSimpleNoExplodeArrayWithResponse request GetSimpleNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeArrayResponse, error) @@ -1837,6 +2184,27 @@ func (r GetLabelExplodeObjectResponse) StatusCode() int { return 0 } +type GetLabelExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetLabelNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -1879,6 +2247,27 @@ func (r GetLabelNoExplodeObjectResponse) StatusCode() int { return 0 } +type GetLabelPrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelPrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelPrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetMatrixExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -1921,6 +2310,27 @@ func (r GetMatrixExplodeObjectResponse) StatusCode() int { return 0 } +type GetMatrixExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetMatrixNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -1963,6 +2373,27 @@ func (r GetMatrixNoExplodeObjectResponse) StatusCode() int { return 0 } +type GetMatrixPrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixPrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixPrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetPassThroughResponse struct { Body []byte HTTPResponse *http.Response @@ -2005,6 +2436,27 @@ func (r GetDeepObjectResponse) StatusCode() int { return 0 } +type GetQueryDelimitedResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetQueryDelimitedResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetQueryDelimitedResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetQueryFormResponse struct { Body []byte HTTPResponse *http.Response @@ -2068,6 +2520,27 @@ func (r GetSimpleExplodeObjectResponse) StatusCode() int { return 0 } +type GetSimpleExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetSimpleNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2206,6 +2679,15 @@ func (c *ClientWithResponses) GetLabelExplodeObjectWithResponse(ctx context.Cont return ParseGetLabelExplodeObjectResponse(rsp) } +// GetLabelExplodePrimitiveWithResponse request returning *GetLabelExplodePrimitiveResponse +func (c *ClientWithResponses) GetLabelExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelExplodePrimitiveResponse, error) { + rsp, err := c.GetLabelExplodePrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelExplodePrimitiveResponse(rsp) +} + // GetLabelNoExplodeArrayWithResponse request returning *GetLabelNoExplodeArrayResponse func (c *ClientWithResponses) GetLabelNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeArrayResponse, error) { rsp, err := c.GetLabelNoExplodeArray(ctx, param, reqEditors...) @@ -2224,6 +2706,15 @@ func (c *ClientWithResponses) GetLabelNoExplodeObjectWithResponse(ctx context.Co return ParseGetLabelNoExplodeObjectResponse(rsp) } +// GetLabelPrimitiveWithResponse request returning *GetLabelPrimitiveResponse +func (c *ClientWithResponses) GetLabelPrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelPrimitiveResponse, error) { + rsp, err := c.GetLabelPrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelPrimitiveResponse(rsp) +} + // GetMatrixExplodeArrayWithResponse request returning *GetMatrixExplodeArrayResponse func (c *ClientWithResponses) GetMatrixExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodeArrayResponse, error) { rsp, err := c.GetMatrixExplodeArray(ctx, id, reqEditors...) @@ -2242,6 +2733,15 @@ func (c *ClientWithResponses) GetMatrixExplodeObjectWithResponse(ctx context.Con return ParseGetMatrixExplodeObjectResponse(rsp) } +// GetMatrixExplodePrimitiveWithResponse request returning *GetMatrixExplodePrimitiveResponse +func (c *ClientWithResponses) GetMatrixExplodePrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodePrimitiveResponse, error) { + rsp, err := c.GetMatrixExplodePrimitive(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixExplodePrimitiveResponse(rsp) +} + // GetMatrixNoExplodeArrayWithResponse request returning *GetMatrixNoExplodeArrayResponse func (c *ClientWithResponses) GetMatrixNoExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeArrayResponse, error) { rsp, err := c.GetMatrixNoExplodeArray(ctx, id, reqEditors...) @@ -2260,6 +2760,15 @@ func (c *ClientWithResponses) GetMatrixNoExplodeObjectWithResponse(ctx context.C return ParseGetMatrixNoExplodeObjectResponse(rsp) } +// GetMatrixPrimitiveWithResponse request returning *GetMatrixPrimitiveResponse +func (c *ClientWithResponses) GetMatrixPrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixPrimitiveResponse, error) { + rsp, err := c.GetMatrixPrimitive(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixPrimitiveResponse(rsp) +} + // GetPassThroughWithResponse request returning *GetPassThroughResponse func (c *ClientWithResponses) GetPassThroughWithResponse(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*GetPassThroughResponse, error) { rsp, err := c.GetPassThrough(ctx, param, reqEditors...) @@ -2278,6 +2787,15 @@ func (c *ClientWithResponses) GetDeepObjectWithResponse(ctx context.Context, par return ParseGetDeepObjectResponse(rsp) } +// GetQueryDelimitedWithResponse request returning *GetQueryDelimitedResponse +func (c *ClientWithResponses) GetQueryDelimitedWithResponse(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*GetQueryDelimitedResponse, error) { + rsp, err := c.GetQueryDelimited(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetQueryDelimitedResponse(rsp) +} + // GetQueryFormWithResponse request returning *GetQueryFormResponse func (c *ClientWithResponses) GetQueryFormWithResponse(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*GetQueryFormResponse, error) { rsp, err := c.GetQueryForm(ctx, params, reqEditors...) @@ -2305,6 +2823,15 @@ func (c *ClientWithResponses) GetSimpleExplodeObjectWithResponse(ctx context.Con return ParseGetSimpleExplodeObjectResponse(rsp) } +// GetSimpleExplodePrimitiveWithResponse request returning *GetSimpleExplodePrimitiveResponse +func (c *ClientWithResponses) GetSimpleExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodePrimitiveResponse, error) { + rsp, err := c.GetSimpleExplodePrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleExplodePrimitiveResponse(rsp) +} + // GetSimpleNoExplodeArrayWithResponse request returning *GetSimpleNoExplodeArrayResponse func (c *ClientWithResponses) GetSimpleNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeArrayResponse, error) { rsp, err := c.GetSimpleNoExplodeArray(ctx, param, reqEditors...) @@ -2437,6 +2964,22 @@ func ParseGetLabelExplodeObjectResponse(rsp *http.Response) (*GetLabelExplodeObj return response, nil } +// ParseGetLabelExplodePrimitiveResponse parses an HTTP response from a GetLabelExplodePrimitiveWithResponse call +func ParseGetLabelExplodePrimitiveResponse(rsp *http.Response) (*GetLabelExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetLabelNoExplodeArrayResponse parses an HTTP response from a GetLabelNoExplodeArrayWithResponse call func ParseGetLabelNoExplodeArrayResponse(rsp *http.Response) (*GetLabelNoExplodeArrayResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2469,6 +3012,22 @@ func ParseGetLabelNoExplodeObjectResponse(rsp *http.Response) (*GetLabelNoExplod return response, nil } +// ParseGetLabelPrimitiveResponse parses an HTTP response from a GetLabelPrimitiveWithResponse call +func ParseGetLabelPrimitiveResponse(rsp *http.Response) (*GetLabelPrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelPrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetMatrixExplodeArrayResponse parses an HTTP response from a GetMatrixExplodeArrayWithResponse call func ParseGetMatrixExplodeArrayResponse(rsp *http.Response) (*GetMatrixExplodeArrayResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2501,6 +3060,22 @@ func ParseGetMatrixExplodeObjectResponse(rsp *http.Response) (*GetMatrixExplodeO return response, nil } +// ParseGetMatrixExplodePrimitiveResponse parses an HTTP response from a GetMatrixExplodePrimitiveWithResponse call +func ParseGetMatrixExplodePrimitiveResponse(rsp *http.Response) (*GetMatrixExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetMatrixNoExplodeArrayResponse parses an HTTP response from a GetMatrixNoExplodeArrayWithResponse call func ParseGetMatrixNoExplodeArrayResponse(rsp *http.Response) (*GetMatrixNoExplodeArrayResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2533,6 +3108,22 @@ func ParseGetMatrixNoExplodeObjectResponse(rsp *http.Response) (*GetMatrixNoExpl return response, nil } +// ParseGetMatrixPrimitiveResponse parses an HTTP response from a GetMatrixPrimitiveWithResponse call +func ParseGetMatrixPrimitiveResponse(rsp *http.Response) (*GetMatrixPrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixPrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetPassThroughResponse parses an HTTP response from a GetPassThroughWithResponse call func ParseGetPassThroughResponse(rsp *http.Response) (*GetPassThroughResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2565,6 +3156,22 @@ func ParseGetDeepObjectResponse(rsp *http.Response) (*GetDeepObjectResponse, err return response, nil } +// ParseGetQueryDelimitedResponse parses an HTTP response from a GetQueryDelimitedWithResponse call +func ParseGetQueryDelimitedResponse(rsp *http.Response) (*GetQueryDelimitedResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetQueryDelimitedResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetQueryFormResponse parses an HTTP response from a GetQueryFormWithResponse call func ParseGetQueryFormResponse(rsp *http.Response) (*GetQueryFormResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2613,6 +3220,22 @@ func ParseGetSimpleExplodeObjectResponse(rsp *http.Response) (*GetSimpleExplodeO return response, nil } +// ParseGetSimpleExplodePrimitiveResponse parses an HTTP response from a GetSimpleExplodePrimitiveWithResponse call +func ParseGetSimpleExplodePrimitiveResponse(rsp *http.Response) (*GetSimpleExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseGetSimpleNoExplodeArrayResponse parses an HTTP response from a GetSimpleNoExplodeArrayWithResponse call func ParseGetSimpleNoExplodeArrayResponse(rsp *http.Response) (*GetSimpleNoExplodeArrayResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -2676,829 +3299,3 @@ func ParseGetStartingWithNumberResponse(rsp *http.Response) (*GetStartingWithNum return response, nil } - -// ServerInterface represents all server handlers. -type ServerInterface interface { - - // (GET /contentObject/{param}) - GetContentObject(ctx echo.Context, param ComplexObject) error - - // (GET /cookie) - GetCookie(ctx echo.Context, params GetCookieParams) error - - // (GET /enums) - EnumParams(ctx echo.Context, params EnumParamsParams) error - - // (GET /header) - GetHeader(ctx echo.Context, params GetHeaderParams) error - - // (GET /labelExplodeArray/{.param*}) - GetLabelExplodeArray(ctx echo.Context, param []int32) error - - // (GET /labelExplodeObject/{.param*}) - GetLabelExplodeObject(ctx echo.Context, param Object) error - - // (GET /labelNoExplodeArray/{.param}) - GetLabelNoExplodeArray(ctx echo.Context, param []int32) error - - // (GET /labelNoExplodeObject/{.param}) - GetLabelNoExplodeObject(ctx echo.Context, param Object) error - - // (GET /matrixExplodeArray/{.id*}) - GetMatrixExplodeArray(ctx echo.Context, id []int32) error - - // (GET /matrixExplodeObject/{.id*}) - GetMatrixExplodeObject(ctx echo.Context, id Object) error - - // (GET /matrixNoExplodeArray/{.id}) - GetMatrixNoExplodeArray(ctx echo.Context, id []int32) error - - // (GET /matrixNoExplodeObject/{.id}) - GetMatrixNoExplodeObject(ctx echo.Context, id Object) error - - // (GET /passThrough/{param}) - GetPassThrough(ctx echo.Context, param string) error - - // (GET /queryDeepObject) - GetDeepObject(ctx echo.Context, params GetDeepObjectParams) error - - // (GET /queryForm) - GetQueryForm(ctx echo.Context, params GetQueryFormParams) error - - // (GET /simpleExplodeArray/{param*}) - GetSimpleExplodeArray(ctx echo.Context, param []int32) error - - // (GET /simpleExplodeObject/{param*}) - GetSimpleExplodeObject(ctx echo.Context, param Object) error - - // (GET /simpleNoExplodeArray/{param}) - GetSimpleNoExplodeArray(ctx echo.Context, param []int32) error - - // (GET /simpleNoExplodeObject/{param}) - GetSimpleNoExplodeObject(ctx echo.Context, param Object) error - - // (GET /simplePrimitive/{param}) - GetSimplePrimitive(ctx echo.Context, param int32) error - - // (GET /startingWithNumber/{1param}) - GetStartingWithNumber(ctx echo.Context, n1param string) error -} - -// ServerInterfaceWrapper converts echo contexts to parameters. -type ServerInterfaceWrapper struct { - Handler ServerInterface -} - -// GetContentObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetContentObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param ComplexObject - - err = json.Unmarshal([]byte(ctx.Param("param")), ¶m) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'param' as JSON") - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetContentObject(ctx, param) - return err -} - -// GetCookie converts echo context to params. -func (w *ServerInterfaceWrapper) GetCookie(ctx echo.Context) error { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params GetCookieParams - - if cookie, err := ctx.Cookie("p"); err == nil { - - var value int32 - err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) - } - params.P = &value - - } - - if cookie, err := ctx.Cookie("ep"); err == nil { - - var value int32 - err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) - } - params.Ep = &value - - } - - if cookie, err := ctx.Cookie("ea"); err == nil { - - var value []int32 - err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) - } - params.Ea = &value - - } - - if cookie, err := ctx.Cookie("a"); err == nil { - - var value []int32 - err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) - } - params.A = &value - - } - - if cookie, err := ctx.Cookie("eo"); err == nil { - - var value Object - err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) - } - params.Eo = &value - - } - - if cookie, err := ctx.Cookie("o"); err == nil { - - var value Object - err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) - } - params.O = &value - - } - - if cookie, err := ctx.Cookie("co"); err == nil { - - var value ComplexObject - var decoded string - decoded, err := url.QueryUnescape(cookie.Value) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Error unescaping cookie parameter 'co'") - } - err = json.Unmarshal([]byte(decoded), &value) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") - } - params.Co = &value - - } - - if cookie, err := ctx.Cookie("1s"); err == nil { - - var value string - err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) - } - params.N1s = &value - - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetCookie(ctx, params) - return err -} - -// EnumParams converts echo context to params. -func (w *ServerInterfaceWrapper) EnumParams(ctx echo.Context) error { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params EnumParamsParams - // ------------- Optional query parameter "enumPathParam" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", ctx.QueryParams(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter enumPathParam: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.EnumParams(ctx, params) - return err -} - -// GetHeader converts echo context to params. -func (w *ServerInterfaceWrapper) GetHeader(ctx echo.Context) error { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params GetHeaderParams - - headers := ctx.Request().Header - // ------------- Optional header parameter "X-Primitive" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { - var XPrimitive int32 - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive: %s", err)) - } - - params.XPrimitive = &XPrimitive - } - // ------------- Optional header parameter "X-Primitive-Exploded" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { - var XPrimitiveExploded int32 - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive-Exploded, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive-Exploded: %s", err)) - } - - params.XPrimitiveExploded = &XPrimitiveExploded - } - // ------------- Optional header parameter "X-Array-Exploded" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { - var XArrayExploded []int32 - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array-Exploded, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array-Exploded: %s", err)) - } - - params.XArrayExploded = &XArrayExploded - } - // ------------- Optional header parameter "X-Array" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { - var XArray []int32 - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array: %s", err)) - } - - params.XArray = &XArray - } - // ------------- Optional header parameter "X-Object-Exploded" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { - var XObjectExploded Object - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object-Exploded, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object-Exploded: %s", err)) - } - - params.XObjectExploded = &XObjectExploded - } - // ------------- Optional header parameter "X-Object" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { - var XObject Object - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object: %s", err)) - } - - params.XObject = &XObject - } - // ------------- Optional header parameter "X-Complex-Object" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { - var XComplexObject ComplexObject - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Complex-Object, got %d", n)) - } - - err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'X-Complex-Object' as JSON") - } - - params.XComplexObject = &XComplexObject - } - // ------------- Optional header parameter "1-Starting-With-Number" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { - var N1StartingWithNumber string - n := len(valueList) - if n != 1 { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for 1-Starting-With-Number, got %d", n)) - } - - err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1-Starting-With-Number: %s", err)) - } - - params.N1StartingWithNumber = &N1StartingWithNumber - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetHeader(ctx, params) - return err -} - -// GetLabelExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetLabelExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param []int32 - - err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetLabelExplodeArray(ctx, param) - return err -} - -// GetLabelExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetLabelExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param Object - - err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetLabelExplodeObject(ctx, param) - return err -} - -// GetLabelNoExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetLabelNoExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param []int32 - - err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetLabelNoExplodeArray(ctx, param) - return err -} - -// GetLabelNoExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetLabelNoExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param Object - - err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetLabelNoExplodeObject(ctx, param) - return err -} - -// GetMatrixExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetMatrixExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id []int32 - - err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetMatrixExplodeArray(ctx, id) - return err -} - -// GetMatrixExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetMatrixExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Object - - err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetMatrixExplodeObject(ctx, id) - return err -} - -// GetMatrixNoExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetMatrixNoExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id []int32 - - err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetMatrixNoExplodeArray(ctx, id) - return err -} - -// GetMatrixNoExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetMatrixNoExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "id" ------------- - var id Object - - err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetMatrixNoExplodeObject(ctx, id) - return err -} - -// GetPassThrough converts echo context to params. -func (w *ServerInterfaceWrapper) GetPassThrough(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param string - - param = ctx.Param("param") - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetPassThrough(ctx, param) - return err -} - -// GetDeepObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetDeepObject(ctx echo.Context) error { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params GetDeepObjectParams - // ------------- Required query parameter "deepObj" ------------- - - err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", ctx.QueryParams(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter deepObj: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetDeepObject(ctx, params) - return err -} - -// GetQueryForm converts echo context to params. -func (w *ServerInterfaceWrapper) GetQueryForm(ctx echo.Context) error { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params GetQueryFormParams - // ------------- Optional query parameter "ea" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", ctx.QueryParams(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) - } - - // ------------- Optional query parameter "a" ------------- - - err = runtime.BindQueryParameterWithOptions("form", false, false, "a", ctx.QueryParams(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) - } - - // ------------- Optional query parameter "eo" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", ctx.QueryParams(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) - } - - // ------------- Optional query parameter "o" ------------- - - err = runtime.BindQueryParameterWithOptions("form", false, false, "o", ctx.QueryParams(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) - } - - // ------------- Optional query parameter "ep" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", ctx.QueryParams(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) - } - - // ------------- Optional query parameter "p" ------------- - - err = runtime.BindQueryParameterWithOptions("form", false, false, "p", ctx.QueryParams(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) - } - - // ------------- Optional query parameter "ps" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", ctx.QueryParams(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ps: %s", err)) - } - - // ------------- Optional query parameter "co" ------------- - - if paramValue := ctx.QueryParam("co"); paramValue != "" { - - var value ComplexObject - err = json.Unmarshal([]byte(paramValue), &value) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") - } - params.Co = &value - - } - - // ------------- Optional query parameter "1s" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", ctx.QueryParams(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetQueryForm(ctx, params) - return err -} - -// GetSimpleExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetSimpleExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param []int32 - - err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetSimpleExplodeArray(ctx, param) - return err -} - -// GetSimpleExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetSimpleExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param Object - - err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetSimpleExplodeObject(ctx, param) - return err -} - -// GetSimpleNoExplodeArray converts echo context to params. -func (w *ServerInterfaceWrapper) GetSimpleNoExplodeArray(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param []int32 - - err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetSimpleNoExplodeArray(ctx, param) - return err -} - -// GetSimpleNoExplodeObject converts echo context to params. -func (w *ServerInterfaceWrapper) GetSimpleNoExplodeObject(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param Object - - err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetSimpleNoExplodeObject(ctx, param) - return err -} - -// GetSimplePrimitive converts echo context to params. -func (w *ServerInterfaceWrapper) GetSimplePrimitive(ctx echo.Context) error { - var err error - // ------------- Path parameter "param" ------------- - var param int32 - - err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) - } - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetSimplePrimitive(ctx, param) - return err -} - -// GetStartingWithNumber converts echo context to params. -func (w *ServerInterfaceWrapper) GetStartingWithNumber(ctx echo.Context) error { - var err error - // ------------- Path parameter "1param" ------------- - var n1param string - - n1param = ctx.Param("1param") - - // Invoke the callback with all the unmarshaled arguments - err = w.Handler.GetStartingWithNumber(ctx, n1param) - return err -} - -// This is a simple interface which specifies echo.Route addition functions which -// are present on both echo.Echo and echo.Group, since we want to allow using -// either of them for path registration -type EchoRouter interface { - CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route - TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route -} - -// RegisterHandlers adds each server route to the EchoRouter. -func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") -} - -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. -func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { - - wrapper := ServerInterfaceWrapper{ - Handler: si, - } - - router.GET(baseURL+"/contentObject/:param", wrapper.GetContentObject) - router.GET(baseURL+"/cookie", wrapper.GetCookie) - router.GET(baseURL+"/enums", wrapper.EnumParams) - router.GET(baseURL+"/header", wrapper.GetHeader) - router.GET(baseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) - router.GET(baseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) - router.GET(baseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) - router.GET(baseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) - router.GET(baseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) - router.GET(baseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) - router.GET(baseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) - router.GET(baseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) - router.GET(baseURL+"/passThrough/:param", wrapper.GetPassThrough) - router.GET(baseURL+"/queryDeepObject", wrapper.GetDeepObject) - router.GET(baseURL+"/queryForm", wrapper.GetQueryForm) - router.GET(baseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) - router.GET(baseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) - router.GET(baseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) - router.GET(baseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) - router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) - router.GET(baseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) - -} - -// Base64 encoded, gzipped, json marshaled Swagger object -var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaUXOjNhD+K8y2Tx1i7Ls+8Za5XtvM9HJpnZnrTCYPCqyDroB0kpwm4+G/dySBAYEx", - "dkyS61uCVvvtfqy+aJdsIGIZZznmSkK4AYGSs1yi+WVJM57iX+Uj/SRiucJc6R8VPqqAp4Tm+jcZJZgR", - "8/yJI4QglaD5PRRF4UOMMhKUK8pyCOHck8avV2F57O4rRgq0qfVj0D8wbfX42S6GG+CCcRSK2uAu4gYa", - "zRXeo4DChwt5Hmc2qHLxjrEUSa4Xa2c/ClxBCD8Edf5BCR58ruMR+G1NBcYQ3lSbfQ1d49y23LZjXFEh", - "1SXJsIcYHwRL+xYcVGPlN1zdGk5pvmJ6c0ojLF9OboDg08W19q6o0u7hGqXyligeUIAPDyikfQ2L2Xw2", - "14aMY044hRDez+azBfjAiUpM/EH5vm1+wYYTQbJCr9yjSVcnS/R71W8DfkP1obnBuBIkQ4VCQnjTqh/C", - "eUojszn4KplTRUOvp10YJRsQmrDBr2gwyNDkUok1Frd+u8bfzee78LZ2gXMQCoMZRIz9Q3GYDWPRoaF9", - "ILigGVX0QRviI09ZjBCuSCqxTCyq3FSpgd+gasVERpQ9BO/fgd85E4U/ClHTswMQn41YosQeEYI8jYUl", - "LViqMJOj8LdPLFpPPJ0whvieLowtLaw6MKN4Ya2AxkmZC91FHKLgOMSpjns7k8ga1Bz2ZhAx6JKg1zyp", - "iFA0v/f+pSrx8nV2Z6Sy18tCtohwpdtVlxhXZJ2qYxUG87UttV6B+ZivsystLHKfwlxVizZF7dZ7IOka", - "ZZXntzWKp0aFGdcquSpFtM5Yr0B4s5jP/Xfz+a0/Qgy6kvuz5ab1JphXVUuZfIIkRjEkr79bi+fKa1K5", - "KZP/++yqsWVSoR2APvtYasOLSG83kHNt3R/EiwnxjqheWY67UVlt6idrCnXeFcF3J9LdREpHVUJHSLbr", - "c3G2LK3PvlCVnF1W1i8m4ym5w7QsDlPAwWZmJOunwbv0H+62rtL1leeYa/BpDpAPUj2ZJsNkCKe8XDc5", - "q9qPQ0nb1YWcgrUxp2tyfi5ZX1Xt56e9b4Cgpuj8j+pqm3+7sg4gbm9pPYe5166tjChBH53SovHwwfvU", - "2XTMwaPx5DVls5uOsG1NHcTY8Vq1h7LDimkycjpSReMR5JxAqL7niurq1GGsPUOl3npVcSLldSLY+j4Z", - "M5e8qs0Hp5IHTLVfZeZo+vRfEHk9ct6VcsNqT4ccI/LhlscZD8TW9dEV4nQLdaHEdcynvoSbFH5lIhvi", - "7M+t0R7KRjXV7lDlVHPEmi+9FQ5sqp2oXiyocc21y9n0o04H8RSA21T3zX/cbKeZ7A9kezpAr9TGHTjD", - "c9NXHkM4wR43KnacHDgpfsbfBPs5tX29GtEpLzvb3u58waYIk7HW+sB5AG1vZ8IwGUPuxX3/XWvZs+8N", - "zximZ2785/Nl38Y3MWWYjKXtB4/x/DQ/zzjMHMXEiOKZkobyb8oXqhI7mw42ixFUdLZN2NgsJu5sNMPm", - "X1Rs3GuRQgiJUjwMgvL/UxRKNdP9QUb4jFAobov/AgAA//8eGGgVvSQAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode -func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) - if err != nil { - return nil, fmt.Errorf("error base64 decoding spec: %w", err) - } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - - return buf.Bytes(), nil -} - -var rawSpec = decodeSpecCached() - -// a naive cached of a decoded swagger spec -func decodeSpecCached() func() ([]byte, error) { - data, err := decodeSpec() - return func() ([]byte, error) { - return data, err - } -} - -// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. -func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { - res := make(map[string]func() ([]byte, error)) - if len(pathToFile) > 0 { - res[pathToFile] = rawSpec - } - - return res -} - -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { - resolvePath := PathToRawSpec("") - - loader := openapi3.NewLoader() - loader.IsExternalRefsAllowed = true - loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { - pathToFile := url.String() - pathToFile = path.Clean(pathToFile) - getSpec, ok := resolvePath[pathToFile] - if !ok { - err1 := fmt.Errorf("path not found: %s", pathToFile) - return nil, err1 - } - return getSpec() - } - var specData []byte - specData, err = rawSpec() - if err != nil { - return - } - swagger, err = loader.LoadFromData(specData) - if err != nil { - return - } - return -} diff --git a/internal/test/parameters/config.yaml b/internal/test/parameters/config.yaml deleted file mode 100644 index 64850f5de5..0000000000 --- a/internal/test/parameters/config.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# yaml-language-server: $schema=../../../configuration-schema.json -package: parameters -generate: - echo-server: true - client: true - models: true - embedded-spec: true -output: parameters.gen.go diff --git a/internal/test/parameters/doc.go b/internal/test/parameters/doc.go index 30d5b502e5..d18914511e 100644 --- a/internal/test/parameters/doc.go +++ b/internal/test/parameters/doc.go @@ -1,3 +1,2 @@ +// Package parameters contains multi-router parameter roundtrip tests. package parameters - -//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml parameters.yaml diff --git a/internal/test/parameters/echo/gen/server.gen.go b/internal/test/parameters/echo/gen/server.gen.go new file mode 100644 index 0000000000..c3c6d36d8f --- /dev/null +++ b/internal/test/parameters/echo/gen/server.gen.go @@ -0,0 +1,977 @@ +// Package echoparamsgen 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 echoparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/labstack/echo/v4" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(ctx echo.Context, param ComplexObject) error + + // (GET /cookie) + GetCookie(ctx echo.Context, params GetCookieParams) error + + // (GET /enums) + EnumParams(ctx echo.Context, params EnumParamsParams) error + + // (GET /header) + GetHeader(ctx echo.Context, params GetHeaderParams) error + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(ctx echo.Context, param []int32) error + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(ctx echo.Context, param Object) error + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(ctx echo.Context, param int32) error + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(ctx echo.Context, param []int32) error + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(ctx echo.Context, param Object) error + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(ctx echo.Context, param int32) error + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(ctx echo.Context, id []int32) error + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(ctx echo.Context, id Object) error + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(ctx echo.Context, id int32) error + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(ctx echo.Context, id []int32) error + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(ctx echo.Context, id Object) error + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(ctx echo.Context, id int32) error + + // (GET /passThrough/{param}) + GetPassThrough(ctx echo.Context, param string) error + + // (GET /queryDeepObject) + GetDeepObject(ctx echo.Context, params GetDeepObjectParams) error + + // (GET /queryDelimited) + GetQueryDelimited(ctx echo.Context, params GetQueryDelimitedParams) error + + // (GET /queryForm) + GetQueryForm(ctx echo.Context, params GetQueryFormParams) error + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(ctx echo.Context, param []int32) error + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(ctx echo.Context, param Object) error + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(ctx echo.Context, param int32) error + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(ctx echo.Context, param []int32) error + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(ctx echo.Context, param Object) error + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(ctx echo.Context, param int32) error + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(ctx echo.Context, n1param string) error +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +// GetContentObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetContentObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(ctx.Param("param")), ¶m) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'param' as JSON") + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetContentObject(ctx, param) + return err +} + +// GetCookie converts echo context to params. +func (w *ServerInterfaceWrapper) GetCookie(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + if cookie, err := ctx.Cookie("p"); err == nil { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) + } + params.P = &value + + } + + if cookie, err := ctx.Cookie("ep"); err == nil { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) + } + params.Ep = &value + + } + + if cookie, err := ctx.Cookie("ea"); err == nil { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) + } + params.Ea = &value + + } + + if cookie, err := ctx.Cookie("a"); err == nil { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) + } + params.A = &value + + } + + if cookie, err := ctx.Cookie("eo"); err == nil { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) + } + params.Eo = &value + + } + + if cookie, err := ctx.Cookie("o"); err == nil { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) + } + params.O = &value + + } + + if cookie, err := ctx.Cookie("co"); err == nil { + + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unescaping cookie parameter 'co'") + } + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") + } + params.Co = &value + + } + + if cookie, err := ctx.Cookie("1s"); err == nil { + + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) + } + params.N1s = &value + + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetCookie(ctx, params) + return err +} + +// EnumParams converts echo context to params. +func (w *ServerInterfaceWrapper) EnumParams(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", ctx.QueryParams(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter enumPathParam: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.EnumParams(ctx, params) + return err +} + +// GetHeader converts echo context to params. +func (w *ServerInterfaceWrapper) GetHeader(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := ctx.Request().Header + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive: %s", err)) + } + + params.XPrimitive = &XPrimitive + } + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive-Exploded: %s", err)) + } + + params.XPrimitiveExploded = &XPrimitiveExploded + } + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array-Exploded: %s", err)) + } + + params.XArrayExploded = &XArrayExploded + } + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array: %s", err)) + } + + params.XArray = &XArray + } + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object-Exploded: %s", err)) + } + + params.XObjectExploded = &XObjectExploded + } + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object: %s", err)) + } + + params.XObject = &XObject + } + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Complex-Object, got %d", n)) + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'X-Complex-Object' as JSON") + } + + params.XComplexObject = &XComplexObject + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for 1-Starting-With-Number, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1-Starting-With-Number: %s", err)) + } + + params.N1StartingWithNumber = &N1StartingWithNumber + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetHeader(ctx, params) + return err +} + +// GetLabelExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodeArray(ctx, param) + return err +} + +// GetLabelExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodeObject(ctx, param) + return err +} + +// GetLabelExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodePrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodePrimitive(ctx, param) + return err +} + +// GetLabelNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelNoExplodeArray(ctx, param) + return err +} + +// GetLabelNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelNoExplodeObject(ctx, param) + return err +} + +// GetLabelPrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelPrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelPrimitive(ctx, param) + return err +} + +// GetMatrixExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodeArray(ctx, id) + return err +} + +// GetMatrixExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodeObject(ctx, id) + return err +} + +// GetMatrixExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodePrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodePrimitive(ctx, id) + return err +} + +// GetMatrixNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixNoExplodeArray(ctx, id) + return err +} + +// GetMatrixNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixNoExplodeObject(ctx, id) + return err +} + +// GetMatrixPrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixPrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixPrimitive(ctx, id) + return err +} + +// GetPassThrough converts echo context to params. +func (w *ServerInterfaceWrapper) GetPassThrough(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param string + + param = ctx.Param("param") + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetPassThrough(ctx, param) + return err +} + +// GetDeepObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetDeepObject(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", ctx.QueryParams(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter deepObj: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetDeepObject(ctx, params) + return err +} + +// GetQueryDelimited converts echo context to params. +func (w *ServerInterfaceWrapper) GetQueryDelimited(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", ctx.QueryParams(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter sa: %s", err)) + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", ctx.QueryParams(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter pa: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetQueryDelimited(ctx, params) + return err +} + +// GetQueryForm converts echo context to params. +func (w *ServerInterfaceWrapper) GetQueryForm(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", ctx.QueryParams(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", ctx.QueryParams(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", ctx.QueryParams(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", ctx.QueryParams(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", ctx.QueryParams(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", ctx.QueryParams(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", ctx.QueryParams(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ps: %s", err)) + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := ctx.QueryParam("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") + } + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", ctx.QueryParams(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetQueryForm(ctx, params) + return err +} + +// GetSimpleExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodeArray(ctx, param) + return err +} + +// GetSimpleExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodeObject(ctx, param) + return err +} + +// GetSimpleExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodePrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodePrimitive(ctx, param) + return err +} + +// GetSimpleNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeArray(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleNoExplodeArray(ctx, param) + return err +} + +// GetSimpleNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeObject(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleNoExplodeObject(ctx, param) + return err +} + +// GetSimplePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimplePrimitive(ctx echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimplePrimitive(ctx, param) + return err +} + +// GetStartingWithNumber converts echo context to params. +func (w *ServerInterfaceWrapper) GetStartingWithNumber(ctx echo.Context) error { + var err error + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = ctx.Param("1param") + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetStartingWithNumber(ctx, n1param) + return err +} + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithBaseURL(router, si, "") +} + +// Registers handlers, and prepends BaseURL to the paths, so that the paths +// can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.GET(baseURL+"/contentObject/:param", wrapper.GetContentObject) + router.GET(baseURL+"/cookie", wrapper.GetCookie) + router.GET(baseURL+"/enums", wrapper.EnumParams) + router.GET(baseURL+"/header", wrapper.GetHeader) + router.GET(baseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) + router.GET(baseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) + router.GET(baseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) + router.GET(baseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) + router.GET(baseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) + router.GET(baseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) + router.GET(baseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) + router.GET(baseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) + router.GET(baseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) + router.GET(baseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) + router.GET(baseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) + router.GET(baseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) + router.GET(baseURL+"/passThrough/:param", wrapper.GetPassThrough) + router.GET(baseURL+"/queryDeepObject", wrapper.GetDeepObject) + router.GET(baseURL+"/queryDelimited", wrapper.GetQueryDelimited) + router.GET(baseURL+"/queryForm", wrapper.GetQueryForm) + router.GET(baseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) + router.GET(baseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) + router.GET(baseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) + router.GET(baseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) + router.GET(baseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) + router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + router.GET(baseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/echo/gen/types.gen.go b/internal/test/parameters/echo/gen/types.gen.go new file mode 100644 index 0000000000..043be6dba0 --- /dev/null +++ b/internal/test/parameters/echo/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package echoparamsgen 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 echoparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/parameters_test.go b/internal/test/parameters/echo/parameters_test.go similarity index 71% rename from internal/test/parameters/parameters_test.go rename to internal/test/parameters/echo/parameters_test.go index 0635301dfa..6e6d63bea5 100644 --- a/internal/test/parameters/parameters_test.go +++ b/internal/test/parameters/echo/parameters_test.go @@ -1,29 +1,30 @@ -package parameters +package echoparams import ( "encoding/json" "fmt" "net/http" - "net/http/httptest" "testing" - "github.com/oapi-codegen/testutil" "github.com/labstack/echo/v4" + "github.com/oapi-codegen/testutil" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + + . "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/echo/gen" ) type testServer struct { - array []int32 - object *Object - complexObject *ComplexObject - passThrough *string - n1param *string - primitive *int32 - primitiveString *string - cookieParams *GetCookieParams - queryParams *GetQueryFormParams - headerParams *GetHeaderParams + array []int32 + object *Object + complexObject *ComplexObject + passThrough *string + n1param *string + primitive *int32 + primitiveString *string + cookieParams *GetCookieParams + queryParams *GetQueryFormParams + queryDelimitedParams *GetQueryDelimitedParams + headerParams *GetHeaderParams } func (t *testServer) reset() { @@ -36,6 +37,7 @@ func (t *testServer) reset() { t.primitiveString = nil t.cookieParams = nil t.queryParams = nil + t.queryDelimitedParams = nil t.headerParams = nil } @@ -141,6 +143,48 @@ func (t *testServer) GetSimplePrimitive(ctx echo.Context, param int32) error { return nil } +// (GET /simpleExplodePrimitive/{param}) +func (t *testServer) GetSimpleExplodePrimitive(ctx echo.Context, param int32) error { + t.primitive = ¶m + return nil +} + +// (GET /labelPrimitive/{.param}) +func (t *testServer) GetLabelPrimitive(ctx echo.Context, param int32) error { + t.primitive = ¶m + return nil +} + +// (GET /labelExplodePrimitive/{.param*}) +func (t *testServer) GetLabelExplodePrimitive(ctx echo.Context, param int32) error { + t.primitive = ¶m + return nil +} + +// (GET /matrixPrimitive/{;id}) +func (t *testServer) GetMatrixPrimitive(ctx echo.Context, id int32) error { + t.primitive = &id + return nil +} + +// (GET /matrixExplodePrimitive/{;id*}) +func (t *testServer) GetMatrixExplodePrimitive(ctx echo.Context, id int32) error { + t.primitive = &id + return nil +} + +// (GET /queryDelimited) +func (t *testServer) GetQueryDelimited(ctx echo.Context, params GetQueryDelimitedParams) error { + t.queryDelimitedParams = ¶ms + if params.Sa != nil { + t.array = *params.Sa + } + if params.Pa != nil { + t.array = *params.Pa + } + return nil +} + // (GET /queryForm) func (t *testServer) GetQueryForm(ctx echo.Context, params GetQueryFormParams) error { t.queryParams = ¶ms @@ -267,7 +311,7 @@ func TestParameterBinding(t *testing.T) { // (GET /passThrough/{param}) result := testutil.NewRequest().Get("/passThrough/some%20string").GoWithHTTPHandler(t, e) assert.Equal(t, http.StatusOK, result.Code()) - require.NotNil(t, ts.passThrough) + assert.NotNil(t, ts.passThrough) assert.EqualValues(t, "some string", *ts.passThrough) ts.reset() @@ -367,6 +411,36 @@ func TestParameterBinding(t *testing.T) { assert.EqualValues(t, &expectedN1Param, ts.n1param) ts.reset() + // (GET /simpleExplodePrimitive/{param}) + result = testutil.NewRequest().Get("/simpleExplodePrimitive/5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, &expectedPrimitive, ts.primitive) + ts.reset() + + // (GET /labelPrimitive/{.param}) + result = testutil.NewRequest().Get("/labelPrimitive/.5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, &expectedPrimitive, ts.primitive) + ts.reset() + + // (GET /labelExplodePrimitive/{.param*}) + result = testutil.NewRequest().Get("/labelExplodePrimitive/.5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, &expectedPrimitive, ts.primitive) + ts.reset() + + // (GET /matrixPrimitive/{;id}) + result = testutil.NewRequest().Get("/matrixPrimitive/;id=5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, &expectedPrimitive, ts.primitive) + ts.reset() + + // (GET /matrixExplodePrimitive/{;id*}) + result = testutil.NewRequest().Get("/matrixExplodePrimitive/;id=5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, &expectedPrimitive, ts.primitive) + ts.reset() + // ---------------------- Test Form Query Parameters ---------------------- // (GET /queryForm) @@ -425,6 +499,25 @@ func TestParameterBinding(t *testing.T) { assert.EqualValues(t, &expectedN1Param, ts.n1param) ts.reset() + // -------------------- Test Delimited Query Parameters -------------------- + // (GET /queryDelimited) + // These styles are not yet supported by the runtime binding layer. + // See https://github.com/oapi-codegen/runtime/issues/116 + + t.Run("spaceDelimited array", func(t *testing.T) { + result = testutil.NewRequest().Get("/queryDelimited?sa=3%204%205").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, expectedArray, ts.array) + ts.reset() + }) + + t.Run("pipeDelimited array", func(t *testing.T) { + result = testutil.NewRequest().Get("/queryDelimited?pa=3|4|5").GoWithHTTPHandler(t, e) + assert.Equal(t, http.StatusOK, result.Code()) + assert.EqualValues(t, expectedArray, ts.array) + ts.reset() + }) + // complex object via deepObject do := `deepObj[Id]=12345&deepObj[IsAdmin]=true&deepObj[Object][firstName]=Alex&deepObj[Object][role]=admin` q = "/queryDeepObject?" + do @@ -515,219 +608,5 @@ func TestParameterBinding(t *testing.T) { ts.reset() } -func doRequest(t *testing.T, e *echo.Echo, code int, req *http.Request) *httptest.ResponseRecorder { - rec := httptest.NewRecorder() - e.ServeHTTP(rec, req) - assert.Equal(t, code, rec.Code) - return rec -} - -func TestClientPathParams(t *testing.T) { - var ts testServer - e := echo.New() - RegisterHandlers(e, &ts) - server := "http://example.com" - - expectedObject := Object{ - FirstName: "Alex", - Role: "admin", - } - - expectedComplexObject := ComplexObject{ - Object: expectedObject, - Id: 12345, - IsAdmin: true, - } - - expectedArray := []int32{3, 4, 5} - - var expectedPrimitive int32 = 5 - - req, err := NewGetPassThroughRequest(server, "some string") - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - require.NotNil(t, ts.passThrough) - assert.Equal(t, "some string", *ts.passThrough) - ts.reset() - - req, err = NewGetStartingWithNumberRequest(server, "some string") - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - require.NotNil(t, ts.n1param) - assert.Equal(t, "some string", *ts.n1param) - ts.reset() - - req, err = NewGetContentObjectRequest(server, expectedComplexObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedComplexObject, ts.complexObject) - ts.reset() - - // Label style - req, err = NewGetLabelExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetLabelNoExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetLabelExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - req, err = NewGetLabelNoExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - // Matrix style - req, err = NewGetMatrixExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetMatrixNoExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetMatrixExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - req, err = NewGetMatrixNoExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - // Simple style - req, err = NewGetSimpleExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetSimpleNoExplodeArrayRequest(server, expectedArray) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, expectedArray, ts.array) - ts.reset() - - req, err = NewGetSimpleExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - req, err = NewGetSimpleNoExplodeObjectRequest(server, expectedObject) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedObject, ts.object) - ts.reset() - - req, err = NewGetSimplePrimitiveRequest(server, expectedPrimitive) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - assert.EqualValues(t, &expectedPrimitive, ts.primitive) - ts.reset() -} - -func TestClientQueryParams(t *testing.T) { - var ts testServer - e := echo.New() - RegisterHandlers(e, &ts) - server := "http://example.com" - - expectedObject1 := Object{ - FirstName: "Alex", - Role: "admin", - } - expectedObject2 := Object{ - FirstName: "Marcin", - Role: "annoyed_at_swagger", - } - - expectedComplexObject := ComplexObject{ - Object: expectedObject2, - Id: 12345, - IsAdmin: true, - } - - expectedArray1 := []int32{3, 4, 5} - expectedArray2 := []int32{6, 7, 8} - - var expectedPrimitive1 int32 = 5 - var expectedPrimitive2 int32 = 100 - var expectedPrimitiveString = "123;456" - - var expectedStartingWithNumber = "111" - - // Check query params - qParams := GetQueryFormParams{ - Ea: &expectedArray1, - A: &expectedArray2, - Eo: &expectedObject1, - O: &expectedObject2, - Ep: &expectedPrimitive1, - P: &expectedPrimitive2, - Ps: &expectedPrimitiveString, - Co: &expectedComplexObject, - N1s: &expectedStartingWithNumber, - } - - req, err := NewGetQueryFormRequest(server, &qParams) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - require.NotNil(t, ts.queryParams) - assert.EqualValues(t, qParams, *ts.queryParams) - ts.reset() - - // Check cookie params - cParams := GetCookieParams{ - Ea: &expectedArray1, - A: &expectedArray2, - Eo: &expectedObject1, - O: &expectedObject2, - Ep: &expectedPrimitive1, - P: &expectedPrimitive2, - Co: &expectedComplexObject, - N1s: &expectedStartingWithNumber, - } - req, err = NewGetCookieRequest(server, &cParams) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - require.NotNil(t, ts.cookieParams) - assert.EqualValues(t, cParams, *ts.cookieParams) - ts.reset() - - // Check Header parameters - hParams := GetHeaderParams{ - XArrayExploded: &expectedArray1, - XArray: &expectedArray2, - XObjectExploded: &expectedObject1, - XObject: &expectedObject2, - XPrimitiveExploded: &expectedPrimitive1, - XPrimitive: &expectedPrimitive2, - XComplexObject: &expectedComplexObject, - N1StartingWithNumber: &expectedStartingWithNumber, - } - req, err = NewGetHeaderRequest(server, &hParams) - assert.NoError(t, err) - doRequest(t, e, http.StatusOK, req) - require.NotNil(t, ts.headerParams) - assert.EqualValues(t, hParams, *ts.headerParams) - ts.reset() -} +// TestClientPathParams, TestClientQueryParams, and the doRequest helper have been +// superseded by the multi-router TestParameterRoundTrip in param_roundtrip_test.go. diff --git a/internal/test/parameters/echo/server.cfg.yaml b/internal/test/parameters/echo/server.cfg.yaml new file mode 100644 index 0000000000..2e7156dae7 --- /dev/null +++ b/internal/test/parameters/echo/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: echoparamsgen +generate: + echo-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/echo/server.go b/internal/test/parameters/echo/server.go new file mode 100644 index 0000000000..dd05c320cd --- /dev/null +++ b/internal/test/parameters/echo/server.go @@ -0,0 +1,44 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package echoparams + +import ( + "net/http" + + "github.com/labstack/echo/v4" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/echo/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func (s *Server) GetContentObject(ctx echo.Context, param gen.ComplexObject) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetCookie(ctx echo.Context, params gen.GetCookieParams) error { return ctx.JSON(http.StatusOK, params) } +func (s *Server) EnumParams(ctx echo.Context, params gen.EnumParamsParams) error { return ctx.NoContent(http.StatusNoContent) } +func (s *Server) GetHeader(ctx echo.Context, params gen.GetHeaderParams) error { return ctx.JSON(http.StatusOK, params) } +func (s *Server) GetLabelExplodeArray(ctx echo.Context, param []int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodeObject(ctx echo.Context, param gen.Object) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodePrimitive(ctx echo.Context, param int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeArray(ctx echo.Context, param []int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeObject(ctx echo.Context, param gen.Object) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetLabelPrimitive(ctx echo.Context, param int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetMatrixExplodeArray(ctx echo.Context, id []int32) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodeObject(ctx echo.Context, id gen.Object) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodePrimitive(ctx echo.Context, id int32) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeArray(ctx echo.Context, id []int32) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeObject(ctx echo.Context, id gen.Object) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixPrimitive(ctx echo.Context, id int32) error { return ctx.JSON(http.StatusOK, id) } +func (s *Server) GetPassThrough(ctx echo.Context, param string) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetDeepObject(ctx echo.Context, params gen.GetDeepObjectParams) error { return ctx.JSON(http.StatusOK, params) } +func (s *Server) GetQueryDelimited(ctx echo.Context, params gen.GetQueryDelimitedParams) error { return ctx.JSON(http.StatusOK, params) } +func (s *Server) GetQueryForm(ctx echo.Context, params gen.GetQueryFormParams) error { return ctx.JSON(http.StatusOK, params) } +func (s *Server) GetSimpleExplodeArray(ctx echo.Context, param []int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodeObject(ctx echo.Context, param gen.Object) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodePrimitive(ctx echo.Context, param int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeArray(ctx echo.Context, param []int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeObject(ctx echo.Context, param gen.Object) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetSimplePrimitive(ctx echo.Context, param int32) error { return ctx.JSON(http.StatusOK, param) } +func (s *Server) GetStartingWithNumber(ctx echo.Context, n1param string) error { return ctx.JSON(http.StatusOK, n1param) } diff --git a/internal/test/parameters/echo/types.cfg.yaml b/internal/test/parameters/echo/types.cfg.yaml new file mode 100644 index 0000000000..fce1d24f13 --- /dev/null +++ b/internal/test/parameters/echo/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: echoparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/echov5/Makefile b/internal/test/parameters/echov5/Makefile new file mode 100644 index 0000000000..54df0d106e --- /dev/null +++ b/internal/test/parameters/echov5/Makefile @@ -0,0 +1,45 @@ +GO_VERSION := $(shell go version | sed -E 's/.*go([0-9]+\.[0-9]+).*/\1/') +MIN_VERSION := 1.25 +VERSION_OK := $(shell printf '%s\n%s' '$(MIN_VERSION)' '$(GO_VERSION)' | sort -V | head -1 | grep -q '^$(MIN_VERSION)$$' && echo yes || echo no) + +lint: +ifeq ($(VERSION_OK),yes) + $(GOBIN)/golangci-lint run ./... +else + @echo "Skipping lint: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif + +lint-ci: +ifeq ($(VERSION_OK),yes) + $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m +else + @echo "Skipping lint-ci: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif + +generate: +ifeq ($(VERSION_OK),yes) + go generate ./... +else + @echo "Skipping generate: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif + +test: +ifeq ($(VERSION_OK),yes) + go test -cover ./... +else + @echo "Skipping test: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif + +tidy: +ifeq ($(VERSION_OK),yes) + go mod tidy +else + @echo "Skipping tidy: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif + +tidy-ci: +ifeq ($(VERSION_OK),yes) + tidied -verbose +else + @echo "Skipping tidy-ci: requires Go >= $(MIN_VERSION), have $(GO_VERSION)" +endif diff --git a/internal/test/parameters/echov5/client.cfg.yaml b/internal/test/parameters/echov5/client.cfg.yaml new file mode 100644 index 0000000000..79dabbe746 --- /dev/null +++ b/internal/test/parameters/echov5/client.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: echov5params +generate: + client: true +output: client.gen.go diff --git a/internal/test/parameters/echov5/client.gen.go b/internal/test/parameters/echov5/client.gen.go new file mode 100644 index 0000000000..09ce4a6ff7 --- /dev/null +++ b/internal/test/parameters/echov5/client.gen.go @@ -0,0 +1,3162 @@ +// Package echov5params 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 echov5params + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetContentObject request + GetContentObject(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetCookie request + GetCookie(ctx context.Context, params *GetCookieParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // EnumParams request + EnumParams(ctx context.Context, params *EnumParamsParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetHeader request + GetHeader(ctx context.Context, params *GetHeaderParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelExplodeArray request + GetLabelExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelExplodeObject request + GetLabelExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelExplodePrimitive request + GetLabelExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelNoExplodeArray request + GetLabelNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelNoExplodeObject request + GetLabelNoExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLabelPrimitive request + GetLabelPrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixExplodeArray request + GetMatrixExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixExplodeObject request + GetMatrixExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixExplodePrimitive request + GetMatrixExplodePrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixNoExplodeArray request + GetMatrixNoExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixNoExplodeObject request + GetMatrixNoExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetMatrixPrimitive request + GetMatrixPrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetPassThrough request + GetPassThrough(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetDeepObject request + GetDeepObject(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetQueryDelimited request + GetQueryDelimited(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetQueryForm request + GetQueryForm(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimpleExplodeArray request + GetSimpleExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimpleExplodeObject request + GetSimpleExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimpleExplodePrimitive request + GetSimpleExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimpleNoExplodeArray request + GetSimpleNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimpleNoExplodeObject request + GetSimpleNoExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSimplePrimitive request + GetSimplePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetStartingWithNumber request + GetStartingWithNumber(ctx context.Context, n1param string, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetContentObject(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetContentObjectRequest(c.Server, param) + 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 *Client) GetCookie(ctx context.Context, params *GetCookieParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetCookieRequest(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 *Client) EnumParams(ctx context.Context, params *EnumParamsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewEnumParamsRequest(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 *Client) GetHeader(ctx context.Context, params *GetHeaderParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetHeaderRequest(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 *Client) GetLabelExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelExplodeArrayRequest(c.Server, param) + 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 *Client) GetLabelExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelExplodeObjectRequest(c.Server, param) + 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 *Client) GetLabelExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelExplodePrimitiveRequest(c.Server, param) + 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 *Client) GetLabelNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelNoExplodeArrayRequest(c.Server, param) + 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 *Client) GetLabelNoExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelNoExplodeObjectRequest(c.Server, param) + 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 *Client) GetLabelPrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLabelPrimitiveRequest(c.Server, param) + 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 *Client) GetMatrixExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixExplodeArrayRequest(c.Server, id) + 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 *Client) GetMatrixExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixExplodeObjectRequest(c.Server, id) + 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 *Client) GetMatrixExplodePrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixExplodePrimitiveRequest(c.Server, id) + 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 *Client) GetMatrixNoExplodeArray(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixNoExplodeArrayRequest(c.Server, id) + 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 *Client) GetMatrixNoExplodeObject(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixNoExplodeObjectRequest(c.Server, id) + 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 *Client) GetMatrixPrimitive(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetMatrixPrimitiveRequest(c.Server, id) + 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 *Client) GetPassThrough(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetPassThroughRequest(c.Server, param) + 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 *Client) GetDeepObject(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDeepObjectRequest(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 *Client) GetQueryDelimited(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetQueryDelimitedRequest(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 *Client) GetQueryForm(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetQueryFormRequest(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 *Client) GetSimpleExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleExplodeArrayRequest(c.Server, param) + 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 *Client) GetSimpleExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleExplodeObjectRequest(c.Server, param) + 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 *Client) GetSimpleExplodePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleExplodePrimitiveRequest(c.Server, param) + 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 *Client) GetSimpleNoExplodeArray(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleNoExplodeArrayRequest(c.Server, param) + 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 *Client) GetSimpleNoExplodeObject(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimpleNoExplodeObjectRequest(c.Server, param) + 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 *Client) GetSimplePrimitive(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSimplePrimitiveRequest(c.Server, param) + 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 *Client) GetStartingWithNumber(ctx context.Context, n1param string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetStartingWithNumberRequest(c.Server, n1param) + 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) +} + +// NewGetContentObjectRequest generates requests for GetContentObject +func NewGetContentObjectRequest(server string, param ComplexObject) (*http.Request, error) { + var err error + + var pathParam0 string + + var pathParamBuf0 []byte + pathParamBuf0, err = json.Marshal(param) + if err != nil { + return nil, err + } + pathParam0 = string(pathParamBuf0) + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/contentObject/%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 + } + + return req, nil +} + +// NewGetCookieRequest generates requests for GetCookie +func NewGetCookieRequest(server string, params *GetCookieParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/cookie") + 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.P != nil { + var cookieParam0 string + + cookieParam0, err = runtime.StyleParamWithOptions("simple", false, "p", *params.P, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + cookie0 := &http.Cookie{ + Name: "p", + Value: cookieParam0, + } + req.AddCookie(cookie0) + } + + if params.Ep != nil { + var cookieParam1 string + + cookieParam1, err = runtime.StyleParamWithOptions("simple", true, "ep", *params.Ep, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + cookie1 := &http.Cookie{ + Name: "ep", + Value: cookieParam1, + } + req.AddCookie(cookie1) + } + + if params.Ea != nil { + var cookieParam2 string + + cookieParam2, err = runtime.StyleParamWithOptions("simple", true, "ea", *params.Ea, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + cookie2 := &http.Cookie{ + Name: "ea", + Value: cookieParam2, + } + req.AddCookie(cookie2) + } + + if params.A != nil { + var cookieParam3 string + + cookieParam3, err = runtime.StyleParamWithOptions("simple", false, "a", *params.A, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + cookie3 := &http.Cookie{ + Name: "a", + Value: cookieParam3, + } + req.AddCookie(cookie3) + } + + if params.Eo != nil { + var cookieParam4 string + + cookieParam4, err = runtime.StyleParamWithOptions("simple", true, "eo", *params.Eo, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + cookie4 := &http.Cookie{ + Name: "eo", + Value: cookieParam4, + } + req.AddCookie(cookie4) + } + + if params.O != nil { + var cookieParam5 string + + cookieParam5, err = runtime.StyleParamWithOptions("simple", false, "o", *params.O, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + cookie5 := &http.Cookie{ + Name: "o", + Value: cookieParam5, + } + req.AddCookie(cookie5) + } + + if params.Co != nil { + var cookieParam6 string + + var cookieParamBuf6 []byte + cookieParamBuf6, err = json.Marshal(*params.Co) + if err != nil { + return nil, err + } + cookieParam6 = url.QueryEscape(string(cookieParamBuf6)) + + cookie6 := &http.Cookie{ + Name: "co", + Value: cookieParam6, + } + req.AddCookie(cookie6) + } + + if params.N1s != nil { + var cookieParam7 string + + cookieParam7, err = runtime.StyleParamWithOptions("simple", true, "1s", *params.N1s, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationCookie, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + cookie7 := &http.Cookie{ + Name: "1s", + Value: cookieParam7, + } + req.AddCookie(cookie7) + } + } + return req, nil +} + +// NewEnumParamsRequest generates requests for EnumParams +func NewEnumParamsRequest(server string, params *EnumParamsParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/enums") + 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.EnumPathParam != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "enumPathParam", *params.EnumPathParam, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); 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 +} + +// NewGetHeaderRequest generates requests for GetHeader +func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/header") + 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.XPrimitive != nil { + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithOptions("simple", false, "X-Primitive", *params.XPrimitive, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Primitive", headerParam0) + } + + if params.XPrimitiveExploded != nil { + var headerParam1 string + + headerParam1, err = runtime.StyleParamWithOptions("simple", true, "X-Primitive-Exploded", *params.XPrimitiveExploded, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Primitive-Exploded", headerParam1) + } + + if params.XArrayExploded != nil { + var headerParam2 string + + headerParam2, err = runtime.StyleParamWithOptions("simple", true, "X-Array-Exploded", *params.XArrayExploded, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Array-Exploded", headerParam2) + } + + if params.XArray != nil { + var headerParam3 string + + headerParam3, err = runtime.StyleParamWithOptions("simple", false, "X-Array", *params.XArray, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Array", headerParam3) + } + + if params.XObjectExploded != nil { + var headerParam4 string + + headerParam4, err = runtime.StyleParamWithOptions("simple", true, "X-Object-Exploded", *params.XObjectExploded, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Object-Exploded", headerParam4) + } + + if params.XObject != nil { + var headerParam5 string + + headerParam5, err = runtime.StyleParamWithOptions("simple", false, "X-Object", *params.XObject, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("X-Object", headerParam5) + } + + if params.XComplexObject != nil { + var headerParam6 string + + var headerParamBuf6 []byte + headerParamBuf6, err = json.Marshal(*params.XComplexObject) + if err != nil { + return nil, err + } + headerParam6 = string(headerParamBuf6) + + req.Header.Set("X-Complex-Object", headerParam6) + } + + if params.N1StartingWithNumber != nil { + var headerParam7 string + + headerParam7, err = runtime.StyleParamWithOptions("simple", false, "1-Starting-With-Number", *params.N1StartingWithNumber, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + req.Header.Set("1-Starting-With-Number", headerParam7) + } + + } + + return req, nil +} + +// NewGetLabelExplodeArrayRequest generates requests for GetLabelExplodeArray +func NewGetLabelExplodeArrayRequest(server string, param []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelExplodeArray/%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 + } + + return req, nil +} + +// NewGetLabelExplodeObjectRequest generates requests for GetLabelExplodeObject +func NewGetLabelExplodeObjectRequest(server string, param Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelExplodeObject/%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 + } + + return req, nil +} + +// NewGetLabelExplodePrimitiveRequest generates requests for GetLabelExplodePrimitive +func NewGetLabelExplodePrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelExplodePrimitive/%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 + } + + return req, nil +} + +// NewGetLabelNoExplodeArrayRequest generates requests for GetLabelNoExplodeArray +func NewGetLabelNoExplodeArrayRequest(server string, param []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelNoExplodeArray/%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 + } + + return req, nil +} + +// NewGetLabelNoExplodeObjectRequest generates requests for GetLabelNoExplodeObject +func NewGetLabelNoExplodeObjectRequest(server string, param Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelNoExplodeObject/%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 + } + + return req, nil +} + +// NewGetLabelPrimitiveRequest generates requests for GetLabelPrimitive +func NewGetLabelPrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("label", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/labelPrimitive/%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 + } + + return req, nil +} + +// NewGetMatrixExplodeArrayRequest generates requests for GetMatrixExplodeArray +func NewGetMatrixExplodeArrayRequest(server string, id []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", true, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixExplodeArray/%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 + } + + return req, nil +} + +// NewGetMatrixExplodeObjectRequest generates requests for GetMatrixExplodeObject +func NewGetMatrixExplodeObjectRequest(server string, id Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", true, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixExplodeObject/%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 + } + + return req, nil +} + +// NewGetMatrixExplodePrimitiveRequest generates requests for GetMatrixExplodePrimitive +func NewGetMatrixExplodePrimitiveRequest(server string, id int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", true, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixExplodePrimitive/%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 + } + + return req, nil +} + +// NewGetMatrixNoExplodeArrayRequest generates requests for GetMatrixNoExplodeArray +func NewGetMatrixNoExplodeArrayRequest(server string, id []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixNoExplodeArray/%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 + } + + return req, nil +} + +// NewGetMatrixNoExplodeObjectRequest generates requests for GetMatrixNoExplodeObject +func NewGetMatrixNoExplodeObjectRequest(server string, id Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixNoExplodeObject/%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 + } + + return req, nil +} + +// NewGetMatrixPrimitiveRequest generates requests for GetMatrixPrimitive +func NewGetMatrixPrimitiveRequest(server string, id int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("matrix", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/matrixPrimitive/%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 + } + + return req, nil +} + +// NewGetPassThroughRequest generates requests for GetPassThrough +func NewGetPassThroughRequest(server string, param string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0 = param + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/passThrough/%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 + } + + return req, nil +} + +// NewGetDeepObjectRequest generates requests for GetDeepObject +func NewGetDeepObjectRequest(server string, params *GetDeepObjectParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/queryDeepObject") + 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 queryFrag, err := runtime.StyleParamWithOptions("deepObject", true, "deepObj", params.DeepObj, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", 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 +} + +// NewGetQueryDelimitedRequest generates requests for GetQueryDelimited +func NewGetQueryDelimitedRequest(server string, params *GetQueryDelimitedParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/queryDelimited") + 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.Sa != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("spaceDelimited", false, "sa", *params.Sa, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Pa != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("pipeDelimited", false, "pa", *params.Pa, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", 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 +} + +// NewGetQueryFormRequest generates requests for GetQueryForm +func NewGetQueryFormRequest(server string, params *GetQueryFormParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/queryForm") + 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.Ea != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ea", *params.Ea, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.A != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", false, "a", *params.A, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Eo != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "eo", *params.Eo, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.O != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", false, "o", *params.O, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Ep != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ep", *params.Ep, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.P != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", false, "p", *params.P, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Ps != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "ps", *params.Ps, 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.Co != nil { + + if queryParamBuf, err := json.Marshal(*params.Co); err != nil { + return nil, err + } else { + queryValues.Add("co", string(queryParamBuf)) + } + + } + + if params.N1s != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "1s", *params.N1s, 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 +} + +// NewGetSimpleExplodeArrayRequest generates requests for GetSimpleExplodeArray +func NewGetSimpleExplodeArrayRequest(server string, param []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleExplodeArray/%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 + } + + return req, nil +} + +// NewGetSimpleExplodeObjectRequest generates requests for GetSimpleExplodeObject +func NewGetSimpleExplodeObjectRequest(server string, param Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleExplodeObject/%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 + } + + return req, nil +} + +// NewGetSimpleExplodePrimitiveRequest generates requests for GetSimpleExplodePrimitive +func NewGetSimpleExplodePrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", true, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleExplodePrimitive/%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 + } + + return req, nil +} + +// NewGetSimpleNoExplodeArrayRequest generates requests for GetSimpleNoExplodeArray +func NewGetSimpleNoExplodeArrayRequest(server string, param []int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "array", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleNoExplodeArray/%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 + } + + return req, nil +} + +// NewGetSimpleNoExplodeObjectRequest generates requests for GetSimpleNoExplodeObject +func NewGetSimpleNoExplodeObjectRequest(server string, param Object) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simpleNoExplodeObject/%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 + } + + return req, nil +} + +// NewGetSimplePrimitiveRequest generates requests for GetSimplePrimitive +func NewGetSimplePrimitiveRequest(server string, param int32) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "param", param, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int32"}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/simplePrimitive/%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 + } + + return req, nil +} + +// NewGetStartingWithNumberRequest generates requests for GetStartingWithNumber +func NewGetStartingWithNumberRequest(server string, n1param string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0 = n1param + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/startingWithNumber/%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 + } + + return req, nil +} + +func (c *Client) 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 *Client) 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 { + // GetContentObjectWithResponse request + GetContentObjectWithResponse(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*GetContentObjectResponse, error) + + // GetCookieWithResponse request + GetCookieWithResponse(ctx context.Context, params *GetCookieParams, reqEditors ...RequestEditorFn) (*GetCookieResponse, error) + + // EnumParamsWithResponse request + EnumParamsWithResponse(ctx context.Context, params *EnumParamsParams, reqEditors ...RequestEditorFn) (*EnumParamsResponse, error) + + // GetHeaderWithResponse request + GetHeaderWithResponse(ctx context.Context, params *GetHeaderParams, reqEditors ...RequestEditorFn) (*GetHeaderResponse, error) + + // GetLabelExplodeArrayWithResponse request + GetLabelExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelExplodeArrayResponse, error) + + // GetLabelExplodeObjectWithResponse request + GetLabelExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelExplodeObjectResponse, error) + + // GetLabelExplodePrimitiveWithResponse request + GetLabelExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelExplodePrimitiveResponse, error) + + // GetLabelNoExplodeArrayWithResponse request + GetLabelNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeArrayResponse, error) + + // GetLabelNoExplodeObjectWithResponse request + GetLabelNoExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeObjectResponse, error) + + // GetLabelPrimitiveWithResponse request + GetLabelPrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelPrimitiveResponse, error) + + // GetMatrixExplodeArrayWithResponse request + GetMatrixExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodeArrayResponse, error) + + // GetMatrixExplodeObjectWithResponse request + GetMatrixExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixExplodeObjectResponse, error) + + // GetMatrixExplodePrimitiveWithResponse request + GetMatrixExplodePrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodePrimitiveResponse, error) + + // GetMatrixNoExplodeArrayWithResponse request + GetMatrixNoExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeArrayResponse, error) + + // GetMatrixNoExplodeObjectWithResponse request + GetMatrixNoExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeObjectResponse, error) + + // GetMatrixPrimitiveWithResponse request + GetMatrixPrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixPrimitiveResponse, error) + + // GetPassThroughWithResponse request + GetPassThroughWithResponse(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*GetPassThroughResponse, error) + + // GetDeepObjectWithResponse request + GetDeepObjectWithResponse(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*GetDeepObjectResponse, error) + + // GetQueryDelimitedWithResponse request + GetQueryDelimitedWithResponse(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*GetQueryDelimitedResponse, error) + + // GetQueryFormWithResponse request + GetQueryFormWithResponse(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*GetQueryFormResponse, error) + + // GetSimpleExplodeArrayWithResponse request + GetSimpleExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodeArrayResponse, error) + + // GetSimpleExplodeObjectWithResponse request + GetSimpleExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetSimpleExplodeObjectResponse, error) + + // GetSimpleExplodePrimitiveWithResponse request + GetSimpleExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodePrimitiveResponse, error) + + // GetSimpleNoExplodeArrayWithResponse request + GetSimpleNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeArrayResponse, error) + + // GetSimpleNoExplodeObjectWithResponse request + GetSimpleNoExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeObjectResponse, error) + + // GetSimplePrimitiveWithResponse request + GetSimplePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimplePrimitiveResponse, error) + + // GetStartingWithNumberWithResponse request + GetStartingWithNumberWithResponse(ctx context.Context, n1param string, reqEditors ...RequestEditorFn) (*GetStartingWithNumberResponse, error) +} + +type GetContentObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetContentObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetContentObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetCookieResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetCookieResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetCookieResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type EnumParamsResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r EnumParamsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r EnumParamsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetHeaderResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetHeaderResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetHeaderResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelNoExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelNoExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelNoExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelNoExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelNoExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelNoExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLabelPrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetLabelPrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLabelPrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixNoExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixNoExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixNoExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixNoExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixNoExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixNoExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetMatrixPrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetMatrixPrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetMatrixPrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetPassThroughResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetPassThroughResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetPassThroughResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetDeepObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetDeepObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDeepObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetQueryDelimitedResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetQueryDelimitedResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetQueryDelimitedResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetQueryFormResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetQueryFormResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetQueryFormResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimpleExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimpleExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimpleExplodePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleExplodePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleExplodePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimpleNoExplodeArrayResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleNoExplodeArrayResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleNoExplodeArrayResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimpleNoExplodeObjectResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimpleNoExplodeObjectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimpleNoExplodeObjectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSimplePrimitiveResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetSimplePrimitiveResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSimplePrimitiveResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetStartingWithNumberResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetStartingWithNumberResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetStartingWithNumberResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetContentObjectWithResponse request returning *GetContentObjectResponse +func (c *ClientWithResponses) GetContentObjectWithResponse(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*GetContentObjectResponse, error) { + rsp, err := c.GetContentObject(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetContentObjectResponse(rsp) +} + +// GetCookieWithResponse request returning *GetCookieResponse +func (c *ClientWithResponses) GetCookieWithResponse(ctx context.Context, params *GetCookieParams, reqEditors ...RequestEditorFn) (*GetCookieResponse, error) { + rsp, err := c.GetCookie(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetCookieResponse(rsp) +} + +// EnumParamsWithResponse request returning *EnumParamsResponse +func (c *ClientWithResponses) EnumParamsWithResponse(ctx context.Context, params *EnumParamsParams, reqEditors ...RequestEditorFn) (*EnumParamsResponse, error) { + rsp, err := c.EnumParams(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseEnumParamsResponse(rsp) +} + +// GetHeaderWithResponse request returning *GetHeaderResponse +func (c *ClientWithResponses) GetHeaderWithResponse(ctx context.Context, params *GetHeaderParams, reqEditors ...RequestEditorFn) (*GetHeaderResponse, error) { + rsp, err := c.GetHeader(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetHeaderResponse(rsp) +} + +// GetLabelExplodeArrayWithResponse request returning *GetLabelExplodeArrayResponse +func (c *ClientWithResponses) GetLabelExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelExplodeArrayResponse, error) { + rsp, err := c.GetLabelExplodeArray(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelExplodeArrayResponse(rsp) +} + +// GetLabelExplodeObjectWithResponse request returning *GetLabelExplodeObjectResponse +func (c *ClientWithResponses) GetLabelExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelExplodeObjectResponse, error) { + rsp, err := c.GetLabelExplodeObject(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelExplodeObjectResponse(rsp) +} + +// GetLabelExplodePrimitiveWithResponse request returning *GetLabelExplodePrimitiveResponse +func (c *ClientWithResponses) GetLabelExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelExplodePrimitiveResponse, error) { + rsp, err := c.GetLabelExplodePrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelExplodePrimitiveResponse(rsp) +} + +// GetLabelNoExplodeArrayWithResponse request returning *GetLabelNoExplodeArrayResponse +func (c *ClientWithResponses) GetLabelNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeArrayResponse, error) { + rsp, err := c.GetLabelNoExplodeArray(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelNoExplodeArrayResponse(rsp) +} + +// GetLabelNoExplodeObjectWithResponse request returning *GetLabelNoExplodeObjectResponse +func (c *ClientWithResponses) GetLabelNoExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetLabelNoExplodeObjectResponse, error) { + rsp, err := c.GetLabelNoExplodeObject(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelNoExplodeObjectResponse(rsp) +} + +// GetLabelPrimitiveWithResponse request returning *GetLabelPrimitiveResponse +func (c *ClientWithResponses) GetLabelPrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetLabelPrimitiveResponse, error) { + rsp, err := c.GetLabelPrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLabelPrimitiveResponse(rsp) +} + +// GetMatrixExplodeArrayWithResponse request returning *GetMatrixExplodeArrayResponse +func (c *ClientWithResponses) GetMatrixExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodeArrayResponse, error) { + rsp, err := c.GetMatrixExplodeArray(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixExplodeArrayResponse(rsp) +} + +// GetMatrixExplodeObjectWithResponse request returning *GetMatrixExplodeObjectResponse +func (c *ClientWithResponses) GetMatrixExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixExplodeObjectResponse, error) { + rsp, err := c.GetMatrixExplodeObject(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixExplodeObjectResponse(rsp) +} + +// GetMatrixExplodePrimitiveWithResponse request returning *GetMatrixExplodePrimitiveResponse +func (c *ClientWithResponses) GetMatrixExplodePrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixExplodePrimitiveResponse, error) { + rsp, err := c.GetMatrixExplodePrimitive(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixExplodePrimitiveResponse(rsp) +} + +// GetMatrixNoExplodeArrayWithResponse request returning *GetMatrixNoExplodeArrayResponse +func (c *ClientWithResponses) GetMatrixNoExplodeArrayWithResponse(ctx context.Context, id []int32, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeArrayResponse, error) { + rsp, err := c.GetMatrixNoExplodeArray(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixNoExplodeArrayResponse(rsp) +} + +// GetMatrixNoExplodeObjectWithResponse request returning *GetMatrixNoExplodeObjectResponse +func (c *ClientWithResponses) GetMatrixNoExplodeObjectWithResponse(ctx context.Context, id Object, reqEditors ...RequestEditorFn) (*GetMatrixNoExplodeObjectResponse, error) { + rsp, err := c.GetMatrixNoExplodeObject(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixNoExplodeObjectResponse(rsp) +} + +// GetMatrixPrimitiveWithResponse request returning *GetMatrixPrimitiveResponse +func (c *ClientWithResponses) GetMatrixPrimitiveWithResponse(ctx context.Context, id int32, reqEditors ...RequestEditorFn) (*GetMatrixPrimitiveResponse, error) { + rsp, err := c.GetMatrixPrimitive(ctx, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetMatrixPrimitiveResponse(rsp) +} + +// GetPassThroughWithResponse request returning *GetPassThroughResponse +func (c *ClientWithResponses) GetPassThroughWithResponse(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*GetPassThroughResponse, error) { + rsp, err := c.GetPassThrough(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetPassThroughResponse(rsp) +} + +// GetDeepObjectWithResponse request returning *GetDeepObjectResponse +func (c *ClientWithResponses) GetDeepObjectWithResponse(ctx context.Context, params *GetDeepObjectParams, reqEditors ...RequestEditorFn) (*GetDeepObjectResponse, error) { + rsp, err := c.GetDeepObject(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetDeepObjectResponse(rsp) +} + +// GetQueryDelimitedWithResponse request returning *GetQueryDelimitedResponse +func (c *ClientWithResponses) GetQueryDelimitedWithResponse(ctx context.Context, params *GetQueryDelimitedParams, reqEditors ...RequestEditorFn) (*GetQueryDelimitedResponse, error) { + rsp, err := c.GetQueryDelimited(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetQueryDelimitedResponse(rsp) +} + +// GetQueryFormWithResponse request returning *GetQueryFormResponse +func (c *ClientWithResponses) GetQueryFormWithResponse(ctx context.Context, params *GetQueryFormParams, reqEditors ...RequestEditorFn) (*GetQueryFormResponse, error) { + rsp, err := c.GetQueryForm(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetQueryFormResponse(rsp) +} + +// GetSimpleExplodeArrayWithResponse request returning *GetSimpleExplodeArrayResponse +func (c *ClientWithResponses) GetSimpleExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodeArrayResponse, error) { + rsp, err := c.GetSimpleExplodeArray(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleExplodeArrayResponse(rsp) +} + +// GetSimpleExplodeObjectWithResponse request returning *GetSimpleExplodeObjectResponse +func (c *ClientWithResponses) GetSimpleExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetSimpleExplodeObjectResponse, error) { + rsp, err := c.GetSimpleExplodeObject(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleExplodeObjectResponse(rsp) +} + +// GetSimpleExplodePrimitiveWithResponse request returning *GetSimpleExplodePrimitiveResponse +func (c *ClientWithResponses) GetSimpleExplodePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimpleExplodePrimitiveResponse, error) { + rsp, err := c.GetSimpleExplodePrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleExplodePrimitiveResponse(rsp) +} + +// GetSimpleNoExplodeArrayWithResponse request returning *GetSimpleNoExplodeArrayResponse +func (c *ClientWithResponses) GetSimpleNoExplodeArrayWithResponse(ctx context.Context, param []int32, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeArrayResponse, error) { + rsp, err := c.GetSimpleNoExplodeArray(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleNoExplodeArrayResponse(rsp) +} + +// GetSimpleNoExplodeObjectWithResponse request returning *GetSimpleNoExplodeObjectResponse +func (c *ClientWithResponses) GetSimpleNoExplodeObjectWithResponse(ctx context.Context, param Object, reqEditors ...RequestEditorFn) (*GetSimpleNoExplodeObjectResponse, error) { + rsp, err := c.GetSimpleNoExplodeObject(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimpleNoExplodeObjectResponse(rsp) +} + +// GetSimplePrimitiveWithResponse request returning *GetSimplePrimitiveResponse +func (c *ClientWithResponses) GetSimplePrimitiveWithResponse(ctx context.Context, param int32, reqEditors ...RequestEditorFn) (*GetSimplePrimitiveResponse, error) { + rsp, err := c.GetSimplePrimitive(ctx, param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSimplePrimitiveResponse(rsp) +} + +// GetStartingWithNumberWithResponse request returning *GetStartingWithNumberResponse +func (c *ClientWithResponses) GetStartingWithNumberWithResponse(ctx context.Context, n1param string, reqEditors ...RequestEditorFn) (*GetStartingWithNumberResponse, error) { + rsp, err := c.GetStartingWithNumber(ctx, n1param, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetStartingWithNumberResponse(rsp) +} + +// ParseGetContentObjectResponse parses an HTTP response from a GetContentObjectWithResponse call +func ParseGetContentObjectResponse(rsp *http.Response) (*GetContentObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetContentObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetCookieResponse parses an HTTP response from a GetCookieWithResponse call +func ParseGetCookieResponse(rsp *http.Response) (*GetCookieResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetCookieResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseEnumParamsResponse parses an HTTP response from a EnumParamsWithResponse call +func ParseEnumParamsResponse(rsp *http.Response) (*EnumParamsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &EnumParamsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetHeaderResponse parses an HTTP response from a GetHeaderWithResponse call +func ParseGetHeaderResponse(rsp *http.Response) (*GetHeaderResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetHeaderResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelExplodeArrayResponse parses an HTTP response from a GetLabelExplodeArrayWithResponse call +func ParseGetLabelExplodeArrayResponse(rsp *http.Response) (*GetLabelExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelExplodeObjectResponse parses an HTTP response from a GetLabelExplodeObjectWithResponse call +func ParseGetLabelExplodeObjectResponse(rsp *http.Response) (*GetLabelExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelExplodePrimitiveResponse parses an HTTP response from a GetLabelExplodePrimitiveWithResponse call +func ParseGetLabelExplodePrimitiveResponse(rsp *http.Response) (*GetLabelExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelNoExplodeArrayResponse parses an HTTP response from a GetLabelNoExplodeArrayWithResponse call +func ParseGetLabelNoExplodeArrayResponse(rsp *http.Response) (*GetLabelNoExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelNoExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelNoExplodeObjectResponse parses an HTTP response from a GetLabelNoExplodeObjectWithResponse call +func ParseGetLabelNoExplodeObjectResponse(rsp *http.Response) (*GetLabelNoExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelNoExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLabelPrimitiveResponse parses an HTTP response from a GetLabelPrimitiveWithResponse call +func ParseGetLabelPrimitiveResponse(rsp *http.Response) (*GetLabelPrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLabelPrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixExplodeArrayResponse parses an HTTP response from a GetMatrixExplodeArrayWithResponse call +func ParseGetMatrixExplodeArrayResponse(rsp *http.Response) (*GetMatrixExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixExplodeObjectResponse parses an HTTP response from a GetMatrixExplodeObjectWithResponse call +func ParseGetMatrixExplodeObjectResponse(rsp *http.Response) (*GetMatrixExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixExplodePrimitiveResponse parses an HTTP response from a GetMatrixExplodePrimitiveWithResponse call +func ParseGetMatrixExplodePrimitiveResponse(rsp *http.Response) (*GetMatrixExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixNoExplodeArrayResponse parses an HTTP response from a GetMatrixNoExplodeArrayWithResponse call +func ParseGetMatrixNoExplodeArrayResponse(rsp *http.Response) (*GetMatrixNoExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixNoExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixNoExplodeObjectResponse parses an HTTP response from a GetMatrixNoExplodeObjectWithResponse call +func ParseGetMatrixNoExplodeObjectResponse(rsp *http.Response) (*GetMatrixNoExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixNoExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetMatrixPrimitiveResponse parses an HTTP response from a GetMatrixPrimitiveWithResponse call +func ParseGetMatrixPrimitiveResponse(rsp *http.Response) (*GetMatrixPrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetMatrixPrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetPassThroughResponse parses an HTTP response from a GetPassThroughWithResponse call +func ParseGetPassThroughResponse(rsp *http.Response) (*GetPassThroughResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetPassThroughResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetDeepObjectResponse parses an HTTP response from a GetDeepObjectWithResponse call +func ParseGetDeepObjectResponse(rsp *http.Response) (*GetDeepObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDeepObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetQueryDelimitedResponse parses an HTTP response from a GetQueryDelimitedWithResponse call +func ParseGetQueryDelimitedResponse(rsp *http.Response) (*GetQueryDelimitedResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetQueryDelimitedResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetQueryFormResponse parses an HTTP response from a GetQueryFormWithResponse call +func ParseGetQueryFormResponse(rsp *http.Response) (*GetQueryFormResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetQueryFormResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimpleExplodeArrayResponse parses an HTTP response from a GetSimpleExplodeArrayWithResponse call +func ParseGetSimpleExplodeArrayResponse(rsp *http.Response) (*GetSimpleExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimpleExplodeObjectResponse parses an HTTP response from a GetSimpleExplodeObjectWithResponse call +func ParseGetSimpleExplodeObjectResponse(rsp *http.Response) (*GetSimpleExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimpleExplodePrimitiveResponse parses an HTTP response from a GetSimpleExplodePrimitiveWithResponse call +func ParseGetSimpleExplodePrimitiveResponse(rsp *http.Response) (*GetSimpleExplodePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleExplodePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimpleNoExplodeArrayResponse parses an HTTP response from a GetSimpleNoExplodeArrayWithResponse call +func ParseGetSimpleNoExplodeArrayResponse(rsp *http.Response) (*GetSimpleNoExplodeArrayResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleNoExplodeArrayResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimpleNoExplodeObjectResponse parses an HTTP response from a GetSimpleNoExplodeObjectWithResponse call +func ParseGetSimpleNoExplodeObjectResponse(rsp *http.Response) (*GetSimpleNoExplodeObjectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimpleNoExplodeObjectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSimplePrimitiveResponse parses an HTTP response from a GetSimplePrimitiveWithResponse call +func ParseGetSimplePrimitiveResponse(rsp *http.Response) (*GetSimplePrimitiveResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSimplePrimitiveResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetStartingWithNumberResponse parses an HTTP response from a GetStartingWithNumberWithResponse call +func ParseGetStartingWithNumberResponse(rsp *http.Response) (*GetStartingWithNumberResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetStartingWithNumberResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/parameters/echov5/echov5_param_test.go b/internal/test/parameters/echov5/echov5_param_test.go new file mode 100644 index 0000000000..12e5eb5206 --- /dev/null +++ b/internal/test/parameters/echov5/echov5_param_test.go @@ -0,0 +1,381 @@ +package echov5params + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/labstack/echo/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEchoV5ParameterRoundTrip(t *testing.T) { + var s Server + e := echo.New() + RegisterHandlers(e, &s) + testImpl(t, e) +} + +func testImpl(t *testing.T, handler http.Handler) { + t.Helper() + + server := "http://example.com" + + expectedObject := Object{ + FirstName: "Alex", + Role: "admin", + } + + expectedComplexObject := ComplexObject{ + Object: expectedObject, + Id: 12345, + IsAdmin: true, + } + + expectedArray := []int32{3, 4, 5} + + var expectedPrimitive int32 = 5 + + doRoundTrip := func(t *testing.T, req *http.Request, target interface{}) { + t.Helper() + req.RequestURI = req.URL.RequestURI() + rec := httptest.NewRecorder() + handler.ServeHTTP(rec, req) + if !assert.Equal(t, http.StatusOK, rec.Code, "server returned %d; body: %s", rec.Code, rec.Body.String()) { + return + } + if target != nil { + require.NoError(t, json.NewDecoder(rec.Body).Decode(target), "failed to decode response body") + } + } + + t.Run("path", func(t *testing.T) { + t.Run("simple", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := NewGetSimplePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("primitive explode", func(t *testing.T) { + req, err := NewGetSimpleExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("array noExplode", func(t *testing.T) { + req, err := NewGetSimpleNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("array explode", func(t *testing.T) { + req, err := NewGetSimpleExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("object noExplode", func(t *testing.T) { + req, err := NewGetSimpleNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + t.Run("object explode", func(t *testing.T) { + req, err := NewGetSimpleExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + t.Run("label", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := NewGetLabelPrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("primitive explode", func(t *testing.T) { + req, err := NewGetLabelExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("array noExplode", func(t *testing.T) { + req, err := NewGetLabelNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("array explode", func(t *testing.T) { + req, err := NewGetLabelExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("object noExplode", func(t *testing.T) { + req, err := NewGetLabelNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + t.Run("object explode", func(t *testing.T) { + req, err := NewGetLabelExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + t.Run("matrix", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := NewGetMatrixPrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("primitive explode", func(t *testing.T) { + req, err := NewGetMatrixExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + t.Run("array noExplode", func(t *testing.T) { + req, err := NewGetMatrixNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("array explode", func(t *testing.T) { + req, err := NewGetMatrixExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + t.Run("object noExplode", func(t *testing.T) { + req, err := NewGetMatrixNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + t.Run("object explode", func(t *testing.T) { + req, err := NewGetMatrixExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + t.Run("content-based", func(t *testing.T) { + t.Run("json complex object", func(t *testing.T) { + req, err := NewGetContentObjectRequest(server, expectedComplexObject) + require.NoError(t, err) + var got ComplexObject + doRoundTrip(t, req, &got) + assert.Equal(t, expectedComplexObject, got) + }) + t.Run("passthrough string", func(t *testing.T) { + req, err := NewGetPassThroughRequest(server, "hello world") + require.NoError(t, err) + var got string + doRoundTrip(t, req, &got) + assert.Equal(t, "hello world", got) + }) + }) + }) + + t.Run("query", func(t *testing.T) { + t.Run("form", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedPrimitiveString = "123;456" + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := GetQueryFormParams{ + Ea: &expectedArray, A: &expectedArray2, + Eo: &expectedObject, O: &expectedObject2, + Ep: &expectedPrimitive, P: &expectedPrimitive2, + Ps: &expectedPrimitiveString, Co: &expectedComplexObject, N1s: &expectedN1s, + } + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + t.Run("exploded array only", func(t *testing.T) { + params := GetQueryFormParams{Ea: &expectedArray} + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Ea) + assert.Equal(t, expectedArray, *got.Ea) + }) + t.Run("unexploded array only", func(t *testing.T) { + params := GetQueryFormParams{A: &expectedArray} + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.A) + assert.Equal(t, expectedArray, *got.A) + }) + t.Run("exploded object only", func(t *testing.T) { + params := GetQueryFormParams{Eo: &expectedObject} + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Eo) + assert.Equal(t, expectedObject, *got.Eo) + }) + t.Run("unexploded object only", func(t *testing.T) { + params := GetQueryFormParams{O: &expectedObject} + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.O) + assert.Equal(t, expectedObject, *got.O) + }) + t.Run("primitive with semicolon", func(t *testing.T) { + params := GetQueryFormParams{Ps: &expectedPrimitiveString} + req, err := NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Ps) + assert.Equal(t, expectedPrimitiveString, *got.Ps) + }) + }) + t.Run("deepObject", func(t *testing.T) { + params := GetDeepObjectParams{DeepObj: expectedComplexObject} + req, err := NewGetDeepObjectRequest(server, ¶ms) + require.NoError(t, err) + var got GetDeepObjectParams + doRoundTrip(t, req, &got) + assert.Equal(t, expectedComplexObject, got.DeepObj) + }) + t.Run("spaceDelimited", func(t *testing.T) { + }) + t.Run("pipeDelimited", func(t *testing.T) { + }) + }) + + t.Run("header", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := GetHeaderParams{ + XPrimitive: &expectedPrimitive2, XPrimitiveExploded: &expectedPrimitive, + XArrayExploded: &expectedArray, XArray: &expectedArray2, + XObjectExploded: &expectedObject, XObject: &expectedObject2, + XComplexObject: &expectedComplexObject, N1StartingWithNumber: &expectedN1s, + } + req, err := NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got GetHeaderParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + t.Run("primitive only", func(t *testing.T) { + params := GetHeaderParams{XPrimitive: &expectedPrimitive} + req, err := NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XPrimitive) + assert.Equal(t, expectedPrimitive, *got.XPrimitive) + }) + t.Run("array only", func(t *testing.T) { + params := GetHeaderParams{XArray: &expectedArray} + req, err := NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XArray) + assert.Equal(t, expectedArray, *got.XArray) + }) + t.Run("object only", func(t *testing.T) { + params := GetHeaderParams{XObject: &expectedObject} + req, err := NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XObject) + assert.Equal(t, expectedObject, *got.XObject) + }) + }) + + t.Run("cookie", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := GetCookieParams{ + P: &expectedPrimitive2, Ep: &expectedPrimitive, + Ea: &expectedArray, A: &expectedArray2, + Eo: &expectedObject, O: &expectedObject2, + Co: &expectedComplexObject, N1s: &expectedN1s, + } + req, err := NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got GetCookieParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + t.Run("primitive only", func(t *testing.T) { + params := GetCookieParams{P: &expectedPrimitive} + req, err := NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.P) + assert.Equal(t, expectedPrimitive, *got.P) + }) + t.Run("array only", func(t *testing.T) { + params := GetCookieParams{A: &expectedArray} + req, err := NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.A) + assert.Equal(t, expectedArray, *got.A) + }) + t.Run("object only", func(t *testing.T) { + params := GetCookieParams{O: &expectedObject} + req, err := NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.O) + assert.Equal(t, expectedObject, *got.O) + }) + }) +} diff --git a/internal/test/parameters/echov5/go.mod b/internal/test/parameters/echov5/go.mod new file mode 100644 index 0000000000..ee22f25588 --- /dev/null +++ b/internal/test/parameters/echov5/go.mod @@ -0,0 +1,41 @@ +module github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/echov5 + +go 1.25.0 + +replace github.com/oapi-codegen/oapi-codegen/v2 => ../../../../ + +tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen + +require ( + github.com/getkin/kin-openapi v0.135.0 + github.com/labstack/echo/v5 v5.0.4 + github.com/oapi-codegen/runtime v1.4.0 + github.com/stretchr/testify v1.11.1 +) + +require ( + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 // indirect + github.com/oasdiff/yaml v0.0.9 // indirect + github.com/oasdiff/yaml3 v0.0.9 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/speakeasy-api/jsonpath v0.6.3 // indirect + github.com/speakeasy-api/openapi v1.19.2 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/internal/test/parameters/echov5/go.sum b/internal/test/parameters/echov5/go.sum new file mode 100644 index 0000000000..4b3a1c089e --- /dev/null +++ b/internal/test/parameters/echov5/go.sum @@ -0,0 +1,190 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= +github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v5 v5.0.4 h1:ll3I/O8BifjMztj9dD1vx/peZQv8cR2CTUdQK6QxGGc= +github.com/labstack/echo/v5 v5.0.4/go.mod h1:SyvlSdObGjRXeQfCCXW/sybkZdOOQZBmpKF0bvALaeo= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= +github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= +github.com/oasdiff/yaml v0.0.9/go.mod h1:8lvhgJG4xiKPj3HN5lDow4jZHPlx1i7dIwzkdAo6oAM= +github.com/oasdiff/yaml3 v0.0.9 h1:rWPrKccrdUm8J0F3sGuU+fuh9+1K/RdJlWF7O/9yw2g= +github.com/oasdiff/yaml3 v0.0.9/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/speakeasy-api/jsonpath v0.6.3 h1:c+QPwzAOdrWvzycuc9HFsIZcxKIaWcNpC+xhOW9rJxU= +github.com/speakeasy-api/jsonpath v0.6.3/go.mod h1:2cXloNuQ+RSXi5HTRaeBh7JEmjRXTiaKpFTdZiL7URI= +github.com/speakeasy-api/openapi v1.19.2 h1:md90tE71/M8jS3cuRlsuWP5Aed4xoG5PSRvXeZgCv/M= +github.com/speakeasy-api/openapi v1.19.2/go.mod h1:UfKa7FqE4jgexJZuj51MmdHAFGmDv0Zaw3+yOd81YKU= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/test/parameters/echov5/server.cfg.yaml b/internal/test/parameters/echov5/server.cfg.yaml new file mode 100644 index 0000000000..49ef08e89f --- /dev/null +++ b/internal/test/parameters/echov5/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: echov5params +generate: + echo5-server: true + embedded-spec: true +output: server.gen.go diff --git a/internal/test/parameters/echov5/server.gen.go b/internal/test/parameters/echov5/server.gen.go new file mode 100644 index 0000000000..748ae76ad1 --- /dev/null +++ b/internal/test/parameters/echov5/server.gen.go @@ -0,0 +1,977 @@ +// Package echov5params 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 echov5params + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/labstack/echo/v5" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(ctx *echo.Context, param ComplexObject) error + + // (GET /cookie) + GetCookie(ctx *echo.Context, params GetCookieParams) error + + // (GET /enums) + EnumParams(ctx *echo.Context, params EnumParamsParams) error + + // (GET /header) + GetHeader(ctx *echo.Context, params GetHeaderParams) error + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(ctx *echo.Context, param []int32) error + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(ctx *echo.Context, param Object) error + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(ctx *echo.Context, param int32) error + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(ctx *echo.Context, param []int32) error + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(ctx *echo.Context, param Object) error + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(ctx *echo.Context, param int32) error + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(ctx *echo.Context, id []int32) error + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(ctx *echo.Context, id Object) error + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(ctx *echo.Context, id int32) error + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(ctx *echo.Context, id []int32) error + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(ctx *echo.Context, id Object) error + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(ctx *echo.Context, id int32) error + + // (GET /passThrough/{param}) + GetPassThrough(ctx *echo.Context, param string) error + + // (GET /queryDeepObject) + GetDeepObject(ctx *echo.Context, params GetDeepObjectParams) error + + // (GET /queryDelimited) + GetQueryDelimited(ctx *echo.Context, params GetQueryDelimitedParams) error + + // (GET /queryForm) + GetQueryForm(ctx *echo.Context, params GetQueryFormParams) error + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(ctx *echo.Context, param []int32) error + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(ctx *echo.Context, param Object) error + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(ctx *echo.Context, param int32) error + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(ctx *echo.Context, param []int32) error + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(ctx *echo.Context, param Object) error + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(ctx *echo.Context, param int32) error + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(ctx *echo.Context, n1param string) error +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +// GetContentObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetContentObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(ctx.Param("param")), ¶m) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'param' as JSON") + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetContentObject(ctx, param) + return err +} + +// GetCookie converts echo context to params. +func (w *ServerInterfaceWrapper) GetCookie(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + if cookie, err := ctx.Cookie("p"); err == nil { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) + } + params.P = &value + + } + + if cookie, err := ctx.Cookie("ep"); err == nil { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) + } + params.Ep = &value + + } + + if cookie, err := ctx.Cookie("ea"); err == nil { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) + } + params.Ea = &value + + } + + if cookie, err := ctx.Cookie("a"); err == nil { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) + } + params.A = &value + + } + + if cookie, err := ctx.Cookie("eo"); err == nil { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) + } + params.Eo = &value + + } + + if cookie, err := ctx.Cookie("o"); err == nil { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) + } + params.O = &value + + } + + if cookie, err := ctx.Cookie("co"); err == nil { + + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unescaping cookie parameter 'co'") + } + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") + } + params.Co = &value + + } + + if cookie, err := ctx.Cookie("1s"); err == nil { + + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) + } + params.N1s = &value + + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetCookie(ctx, params) + return err +} + +// EnumParams converts echo context to params. +func (w *ServerInterfaceWrapper) EnumParams(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", ctx.QueryParams(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter enumPathParam: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.EnumParams(ctx, params) + return err +} + +// GetHeader converts echo context to params. +func (w *ServerInterfaceWrapper) GetHeader(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := ctx.Request().Header + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive: %s", err)) + } + + params.XPrimitive = &XPrimitive + } + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Primitive-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Primitive-Exploded: %s", err)) + } + + params.XPrimitiveExploded = &XPrimitiveExploded + } + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array-Exploded: %s", err)) + } + + params.XArrayExploded = &XArrayExploded + } + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Array, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Array: %s", err)) + } + + params.XArray = &XArray + } + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object-Exploded, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object-Exploded: %s", err)) + } + + params.XObjectExploded = &XObjectExploded + } + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Object, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Object: %s", err)) + } + + params.XObject = &XObject + } + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Complex-Object, got %d", n)) + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'X-Complex-Object' as JSON") + } + + params.XComplexObject = &XComplexObject + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for 1-Starting-With-Number, got %d", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1-Starting-With-Number: %s", err)) + } + + params.N1StartingWithNumber = &N1StartingWithNumber + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetHeader(ctx, params) + return err +} + +// GetLabelExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodeArray(ctx, param) + return err +} + +// GetLabelExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodeObject(ctx, param) + return err +} + +// GetLabelExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodePrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelExplodePrimitive(ctx, param) + return err +} + +// GetLabelNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelNoExplodeArray(ctx, param) + return err +} + +// GetLabelNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelNoExplodeObject(ctx, param) + return err +} + +// GetLabelPrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetLabelPrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetLabelPrimitive(ctx, param) + return err +} + +// GetMatrixExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodeArray(ctx, id) + return err +} + +// GetMatrixExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodeObject(ctx, id) + return err +} + +// GetMatrixExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodePrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixExplodePrimitive(ctx, id) + return err +} + +// GetMatrixNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixNoExplodeArray(ctx, id) + return err +} + +// GetMatrixNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixNoExplodeObject(ctx, id) + return err +} + +// GetMatrixPrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetMatrixPrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMatrixPrimitive(ctx, id) + return err +} + +// GetPassThrough converts echo context to params. +func (w *ServerInterfaceWrapper) GetPassThrough(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param string + + param = ctx.Param("param") + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetPassThrough(ctx, param) + return err +} + +// GetDeepObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetDeepObject(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", ctx.QueryParams(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter deepObj: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetDeepObject(ctx, params) + return err +} + +// GetQueryDelimited converts echo context to params. +func (w *ServerInterfaceWrapper) GetQueryDelimited(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", ctx.QueryParams(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter sa: %s", err)) + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", ctx.QueryParams(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter pa: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetQueryDelimited(ctx, params) + return err +} + +// GetQueryForm converts echo context to params. +func (w *ServerInterfaceWrapper) GetQueryForm(ctx *echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", ctx.QueryParams(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ea: %s", err)) + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", ctx.QueryParams(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter a: %s", err)) + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", ctx.QueryParams(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter eo: %s", err)) + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", ctx.QueryParams(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter o: %s", err)) + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", ctx.QueryParams(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ep: %s", err)) + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", ctx.QueryParams(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter p: %s", err)) + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", ctx.QueryParams(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter ps: %s", err)) + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := ctx.QueryParam("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Error unmarshaling parameter 'co' as JSON") + } + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", ctx.QueryParams(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter 1s: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetQueryForm(ctx, params) + return err +} + +// GetSimpleExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodeArray(ctx, param) + return err +} + +// GetSimpleExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodeObject(ctx, param) + return err +} + +// GetSimpleExplodePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodePrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleExplodePrimitive(ctx, param) + return err +} + +// GetSimpleNoExplodeArray converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeArray(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleNoExplodeArray(ctx, param) + return err +} + +// GetSimpleNoExplodeObject converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeObject(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimpleNoExplodeObject(ctx, param) + return err +} + +// GetSimplePrimitive converts echo context to params. +func (w *ServerInterfaceWrapper) GetSimplePrimitive(ctx *echo.Context) error { + var err error + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter param: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetSimplePrimitive(ctx, param) + return err +} + +// GetStartingWithNumber converts echo context to params. +func (w *ServerInterfaceWrapper) GetStartingWithNumber(ctx *echo.Context) error { + var err error + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = ctx.Param("1param") + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetStartingWithNumber(ctx, n1param) + return err +} + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithBaseURL(router, si, "") +} + +// Registers handlers, and prepends BaseURL to the paths, so that the paths +// can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.GET(baseURL+"/contentObject/:param", wrapper.GetContentObject) + router.GET(baseURL+"/cookie", wrapper.GetCookie) + router.GET(baseURL+"/enums", wrapper.EnumParams) + router.GET(baseURL+"/header", wrapper.GetHeader) + router.GET(baseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) + router.GET(baseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) + router.GET(baseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) + router.GET(baseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) + router.GET(baseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) + router.GET(baseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) + router.GET(baseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) + router.GET(baseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) + router.GET(baseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) + router.GET(baseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) + router.GET(baseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) + router.GET(baseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) + router.GET(baseURL+"/passThrough/:param", wrapper.GetPassThrough) + router.GET(baseURL+"/queryDeepObject", wrapper.GetDeepObject) + router.GET(baseURL+"/queryDelimited", wrapper.GetQueryDelimited) + router.GET(baseURL+"/queryForm", wrapper.GetQueryForm) + router.GET(baseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) + router.GET(baseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) + router.GET(baseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) + router.GET(baseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) + router.GET(baseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) + router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + router.GET(baseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/echov5/server.go b/internal/test/parameters/echov5/server.go new file mode 100644 index 0000000000..50e16af349 --- /dev/null +++ b/internal/test/parameters/echov5/server.go @@ -0,0 +1,41 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=client.cfg.yaml ../parameters.yaml + +package echov5params + +import ( + "net/http" + + "github.com/labstack/echo/v5" +) + +type Server struct{} + +func (s *Server) GetContentObject(ctx *echo.Context, param ComplexObject) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetCookie(ctx *echo.Context, params GetCookieParams) error { return (*ctx).JSON(http.StatusOK, params) } +func (s *Server) EnumParams(ctx *echo.Context, params EnumParamsParams) error { return (*ctx).NoContent(http.StatusNoContent) } +func (s *Server) GetHeader(ctx *echo.Context, params GetHeaderParams) error { return (*ctx).JSON(http.StatusOK, params) } +func (s *Server) GetLabelExplodeArray(ctx *echo.Context, param []int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodeObject(ctx *echo.Context, param Object) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodePrimitive(ctx *echo.Context, param int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeArray(ctx *echo.Context, param []int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeObject(ctx *echo.Context, param Object) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetLabelPrimitive(ctx *echo.Context, param int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetMatrixExplodeArray(ctx *echo.Context, id []int32) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodeObject(ctx *echo.Context, id Object) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodePrimitive(ctx *echo.Context, id int32) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeArray(ctx *echo.Context, id []int32) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeObject(ctx *echo.Context, id Object) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetMatrixPrimitive(ctx *echo.Context, id int32) error { return (*ctx).JSON(http.StatusOK, id) } +func (s *Server) GetPassThrough(ctx *echo.Context, param string) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetDeepObject(ctx *echo.Context, params GetDeepObjectParams) error { return (*ctx).JSON(http.StatusOK, params) } +func (s *Server) GetQueryDelimited(ctx *echo.Context, params GetQueryDelimitedParams) error { return (*ctx).JSON(http.StatusOK, params) } +func (s *Server) GetQueryForm(ctx *echo.Context, params GetQueryFormParams) error { return (*ctx).JSON(http.StatusOK, params) } +func (s *Server) GetSimpleExplodeArray(ctx *echo.Context, param []int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodeObject(ctx *echo.Context, param Object) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodePrimitive(ctx *echo.Context, param int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeArray(ctx *echo.Context, param []int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeObject(ctx *echo.Context, param Object) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetSimplePrimitive(ctx *echo.Context, param int32) error { return (*ctx).JSON(http.StatusOK, param) } +func (s *Server) GetStartingWithNumber(ctx *echo.Context, n1param string) error { return (*ctx).JSON(http.StatusOK, n1param) } diff --git a/internal/test/parameters/echov5/types.cfg.yaml b/internal/test/parameters/echov5/types.cfg.yaml new file mode 100644 index 0000000000..7cf80b491c --- /dev/null +++ b/internal/test/parameters/echov5/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: echov5params +generate: + models: true +output: types.gen.go diff --git a/internal/test/parameters/echov5/types.gen.go b/internal/test/parameters/echov5/types.gen.go new file mode 100644 index 0000000000..ec30efbad9 --- /dev/null +++ b/internal/test/parameters/echov5/types.gen.go @@ -0,0 +1,143 @@ +// Package echov5params 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 echov5params + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/fiber/gen/server.gen.go b/internal/test/parameters/fiber/gen/server.gen.go new file mode 100644 index 0000000000..a615749192 --- /dev/null +++ b/internal/test/parameters/fiber/gen/server.gen.go @@ -0,0 +1,1430 @@ +// Package fiberparamsgen 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 fiberparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/gofiber/fiber/v2" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(c *fiber.Ctx, param ComplexObject) error + + // (GET /cookie) + GetCookie(c *fiber.Ctx, params GetCookieParams) error + + // (GET /enums) + EnumParams(c *fiber.Ctx, params EnumParamsParams) error + + // (GET /header) + GetHeader(c *fiber.Ctx, params GetHeaderParams) error + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(c *fiber.Ctx, param []int32) error + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(c *fiber.Ctx, param Object) error + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(c *fiber.Ctx, param int32) error + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(c *fiber.Ctx, param []int32) error + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(c *fiber.Ctx, param Object) error + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(c *fiber.Ctx, param int32) error + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(c *fiber.Ctx, id []int32) error + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(c *fiber.Ctx, id Object) error + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(c *fiber.Ctx, id int32) error + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(c *fiber.Ctx, id []int32) error + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(c *fiber.Ctx, id Object) error + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(c *fiber.Ctx, id int32) error + + // (GET /passThrough/{param}) + GetPassThrough(c *fiber.Ctx, param string) error + + // (GET /queryDeepObject) + GetDeepObject(c *fiber.Ctx, params GetDeepObjectParams) error + + // (GET /queryDelimited) + GetQueryDelimited(c *fiber.Ctx, params GetQueryDelimitedParams) error + + // (GET /queryForm) + GetQueryForm(c *fiber.Ctx, params GetQueryFormParams) error + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(c *fiber.Ctx, param []int32) error + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(c *fiber.Ctx, param Object) error + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(c *fiber.Ctx, param int32) error + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(c *fiber.Ctx, param []int32) error + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(c *fiber.Ctx, param Object) error + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(c *fiber.Ctx, param int32) error + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(c *fiber.Ctx, n1param string) error +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc +} + +type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error + +// GetContentObject operation middleware +func (siw *ServerInterfaceWrapper) GetContentObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + { + paramValue, decErr := url.PathUnescape(c.Params("param")) + if decErr != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping path parameter 'param': %w", decErr).Error()) + } + err = json.Unmarshal([]byte(paramValue), ¶m) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter 'param' as JSON: %w", err).Error()) + } + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetContentObject(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetCookie operation middleware +func (siw *ServerInterfaceWrapper) GetCookie(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + { + cookie := c.Cookies("p") + + if cookie != "" { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter p: %w", err).Error()) + } + params.P = &value + + } + } + + { + cookie := c.Cookies("ep") + + if cookie != "" { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter ep: %w", err).Error()) + } + params.Ep = &value + + } + } + + { + cookie := c.Cookies("ea") + + if cookie != "" { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter ea: %w", err).Error()) + } + params.Ea = &value + + } + } + + { + cookie := c.Cookies("a") + + if cookie != "" { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter a: %w", err).Error()) + } + params.A = &value + + } + } + + { + cookie := c.Cookies("eo") + + if cookie != "" { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter eo: %w", err).Error()) + } + params.Eo = &value + + } + } + + { + cookie := c.Cookies("o") + + if cookie != "" { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter o: %w", err).Error()) + } + params.O = &value + + } + } + + { + cookie := c.Cookies("co") + + if cookie != "" { + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping cookie parameter 'co': %w", err).Error()) + } + + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter 'co' as JSON: %w", err).Error()) + } + + params.Co = &value + + } + } + + { + cookie := c.Cookies("1s") + + if cookie != "" { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter 1s: %w", err).Error()) + } + params.N1s = &value + + } + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetCookie(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// EnumParams operation middleware +func (siw *ServerInterfaceWrapper) EnumParams(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + + var query url.Values + query, err = url.ParseQuery(string(c.Request().URI().QueryString())) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for query string: %w", err).Error()) + } + + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", query, ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter enumPathParam: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.EnumParams(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetHeader operation middleware +func (siw *ServerInterfaceWrapper) GetHeader(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := c.GetReqHeaders() + + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Primitive, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Primitive: %w", err).Error()) + } + + params.XPrimitive = &XPrimitive + + } + + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Primitive-Exploded, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Primitive-Exploded: %w", err).Error()) + } + + params.XPrimitiveExploded = &XPrimitiveExploded + + } + + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Array-Exploded, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Array-Exploded: %w", err).Error()) + } + + params.XArrayExploded = &XArrayExploded + + } + + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Array, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Array: %w", err).Error()) + } + + params.XArray = &XArray + + } + + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Object-Exploded, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Object-Exploded: %w", err).Error()) + } + + params.XObjectExploded = &XObjectExploded + + } + + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Object, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter X-Object: %w", err).Error()) + } + + params.XObject = &XObject + + } + + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Complex-Object, 1 is required, but %d found", n)) + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter 'X-Complex-Object' as JSON: %w", err).Error()) + } + + params.XComplexObject = &XComplexObject + + } + + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName 1-Starting-With-Number, 1 is required, but %d found", n)) + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter 1-Starting-With-Number: %w", err).Error()) + } + + params.N1StartingWithNumber = &N1StartingWithNumber + + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetHeader(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelExplodeArray(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelExplodeObject(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodePrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelExplodePrimitive(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelNoExplodeArray(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelNoExplodeObject(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetLabelPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelPrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetLabelPrimitive(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixExplodeArray(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixExplodeObject(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodePrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixExplodePrimitive(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixNoExplodeArray(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixNoExplodeObject(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetMatrixPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixPrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetMatrixPrimitive(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetPassThrough operation middleware +func (siw *ServerInterfaceWrapper) GetPassThrough(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param, err = url.PathUnescape(c.Params("param")) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping path parameter 'param': %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetPassThrough(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetDeepObject operation middleware +func (siw *ServerInterfaceWrapper) GetDeepObject(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + + var query url.Values + query, err = url.ParseQuery(string(c.Request().URI().QueryString())) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for query string: %w", err).Error()) + } + + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", query, ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter deepObj: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetDeepObject(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetQueryDelimited operation middleware +func (siw *ServerInterfaceWrapper) GetQueryDelimited(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + + var query url.Values + query, err = url.ParseQuery(string(c.Request().URI().QueryString())) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for query string: %w", err).Error()) + } + + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", query, ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter sa: %w", err).Error()) + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", query, ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter pa: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetQueryDelimited(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetQueryForm operation middleware +func (siw *ServerInterfaceWrapper) GetQueryForm(c *fiber.Ctx) error { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + + var query url.Values + query, err = url.ParseQuery(string(c.Request().URI().QueryString())) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for query string: %w", err).Error()) + } + + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", query, ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter ea: %w", err).Error()) + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", query, ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter a: %w", err).Error()) + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", query, ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter eo: %w", err).Error()) + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", query, ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter o: %w", err).Error()) + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", query, ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter ep: %w", err).Error()) + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", query, ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter p: %w", err).Error()) + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", query, ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter ps: %w", err).Error()) + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := c.Query("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter 'co' as JSON: %w", err).Error()) + } + + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", query, ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter 1s: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetQueryForm(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimpleExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimpleExplodeArray(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimpleExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimpleExplodeObject(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimpleExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodePrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimpleExplodePrimitive(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimpleNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeArray(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimpleNoExplodeArray(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimpleNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeObject(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimpleNoExplodeObject(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetSimplePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimplePrimitive(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Params("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter param: %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetSimplePrimitive(c, param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// GetStartingWithNumber operation middleware +func (siw *ServerInterfaceWrapper) GetStartingWithNumber(c *fiber.Ctx) error { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param, err = url.PathUnescape(c.Params("1param")) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping path parameter '1param': %w", err).Error()) + } + + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetStartingWithNumber(c, n1param) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + +// FiberServerOptions provides options for the Fiber server. +type FiberServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router fiber.Router, si ServerInterface) { + RegisterHandlersWithOptions(router, si, FiberServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, + } + + for _, m := range options.Middlewares { + router.Use(fiber.Handler(m)) + } + + router.Get(options.BaseURL+"/contentObject/:param", wrapper.GetContentObject) + + router.Get(options.BaseURL+"/cookie", wrapper.GetCookie) + + router.Get(options.BaseURL+"/enums", wrapper.EnumParams) + + router.Get(options.BaseURL+"/header", wrapper.GetHeader) + + router.Get(options.BaseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) + + router.Get(options.BaseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) + + router.Get(options.BaseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) + + router.Get(options.BaseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) + + router.Get(options.BaseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) + + router.Get(options.BaseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) + + router.Get(options.BaseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) + + router.Get(options.BaseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) + + router.Get(options.BaseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) + + router.Get(options.BaseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) + + router.Get(options.BaseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) + + router.Get(options.BaseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) + + router.Get(options.BaseURL+"/passThrough/:param", wrapper.GetPassThrough) + + router.Get(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject) + + router.Get(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited) + + router.Get(options.BaseURL+"/queryForm", wrapper.GetQueryForm) + + router.Get(options.BaseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) + + router.Get(options.BaseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) + + router.Get(options.BaseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) + + router.Get(options.BaseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) + + router.Get(options.BaseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) + + router.Get(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + + router.Get(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/fiber/gen/types.gen.go b/internal/test/parameters/fiber/gen/types.gen.go new file mode 100644 index 0000000000..c7b09599fb --- /dev/null +++ b/internal/test/parameters/fiber/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package fiberparamsgen 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 fiberparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/fiber/server.cfg.yaml b/internal/test/parameters/fiber/server.cfg.yaml new file mode 100644 index 0000000000..02818417f9 --- /dev/null +++ b/internal/test/parameters/fiber/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: fiberparamsgen +generate: + fiber-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/fiber/server.go b/internal/test/parameters/fiber/server.go new file mode 100644 index 0000000000..23431a9fe4 --- /dev/null +++ b/internal/test/parameters/fiber/server.go @@ -0,0 +1,44 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package fiberparams + +import ( + "net/http" + + "github.com/gofiber/fiber/v2" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/fiber/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func (s *Server) GetContentObject(c *fiber.Ctx, param gen.ComplexObject) error { return c.JSON(param) } +func (s *Server) GetCookie(c *fiber.Ctx, params gen.GetCookieParams) error { return c.JSON(params) } +func (s *Server) EnumParams(c *fiber.Ctx, params gen.EnumParamsParams) error { return c.SendStatus(http.StatusNoContent) } +func (s *Server) GetHeader(c *fiber.Ctx, params gen.GetHeaderParams) error { return c.JSON(params) } +func (s *Server) GetLabelExplodeArray(c *fiber.Ctx, param []int32) error { return c.JSON(param) } +func (s *Server) GetLabelExplodeObject(c *fiber.Ctx, param gen.Object) error { return c.JSON(param) } +func (s *Server) GetLabelExplodePrimitive(c *fiber.Ctx, param int32) error { return c.JSON(param) } +func (s *Server) GetLabelNoExplodeArray(c *fiber.Ctx, param []int32) error { return c.JSON(param) } +func (s *Server) GetLabelNoExplodeObject(c *fiber.Ctx, param gen.Object) error { return c.JSON(param) } +func (s *Server) GetLabelPrimitive(c *fiber.Ctx, param int32) error { return c.JSON(param) } +func (s *Server) GetMatrixExplodeArray(c *fiber.Ctx, id []int32) error { return c.JSON(id) } +func (s *Server) GetMatrixExplodeObject(c *fiber.Ctx, id gen.Object) error { return c.JSON(id) } +func (s *Server) GetMatrixExplodePrimitive(c *fiber.Ctx, id int32) error { return c.JSON(id) } +func (s *Server) GetMatrixNoExplodeArray(c *fiber.Ctx, id []int32) error { return c.JSON(id) } +func (s *Server) GetMatrixNoExplodeObject(c *fiber.Ctx, id gen.Object) error { return c.JSON(id) } +func (s *Server) GetMatrixPrimitive(c *fiber.Ctx, id int32) error { return c.JSON(id) } +func (s *Server) GetPassThrough(c *fiber.Ctx, param string) error { return c.JSON(param) } +func (s *Server) GetDeepObject(c *fiber.Ctx, params gen.GetDeepObjectParams) error { return c.JSON(params) } +func (s *Server) GetQueryDelimited(c *fiber.Ctx, params gen.GetQueryDelimitedParams) error { return c.JSON(params) } +func (s *Server) GetQueryForm(c *fiber.Ctx, params gen.GetQueryFormParams) error { return c.JSON(params) } +func (s *Server) GetSimpleExplodeArray(c *fiber.Ctx, param []int32) error { return c.JSON(param) } +func (s *Server) GetSimpleExplodeObject(c *fiber.Ctx, param gen.Object) error { return c.JSON(param) } +func (s *Server) GetSimpleExplodePrimitive(c *fiber.Ctx, param int32) error { return c.JSON(param) } +func (s *Server) GetSimpleNoExplodeArray(c *fiber.Ctx, param []int32) error { return c.JSON(param) } +func (s *Server) GetSimpleNoExplodeObject(c *fiber.Ctx, param gen.Object) error { return c.JSON(param) } +func (s *Server) GetSimplePrimitive(c *fiber.Ctx, param int32) error { return c.JSON(param) } +func (s *Server) GetStartingWithNumber(c *fiber.Ctx, n1param string) error { return c.JSON(n1param) } diff --git a/internal/test/parameters/fiber/types.cfg.yaml b/internal/test/parameters/fiber/types.cfg.yaml new file mode 100644 index 0000000000..4f12092b04 --- /dev/null +++ b/internal/test/parameters/fiber/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: fiberparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/gin/gen/server.gen.go b/internal/test/parameters/gin/gen/server.gen.go new file mode 100644 index 0000000000..257d7106e0 --- /dev/null +++ b/internal/test/parameters/gin/gen/server.gen.go @@ -0,0 +1,1293 @@ +// Package ginparamsgen 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 ginparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/gin-gonic/gin" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(c *gin.Context, param ComplexObject) + + // (GET /cookie) + GetCookie(c *gin.Context, params GetCookieParams) + + // (GET /enums) + EnumParams(c *gin.Context, params EnumParamsParams) + + // (GET /header) + GetHeader(c *gin.Context, params GetHeaderParams) + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(c *gin.Context, param []int32) + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(c *gin.Context, param Object) + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(c *gin.Context, param int32) + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(c *gin.Context, param []int32) + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(c *gin.Context, param Object) + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(c *gin.Context, param int32) + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(c *gin.Context, id []int32) + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(c *gin.Context, id Object) + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(c *gin.Context, id int32) + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(c *gin.Context, id []int32) + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(c *gin.Context, id Object) + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(c *gin.Context, id int32) + + // (GET /passThrough/{param}) + GetPassThrough(c *gin.Context, param string) + + // (GET /queryDeepObject) + GetDeepObject(c *gin.Context, params GetDeepObjectParams) + + // (GET /queryDelimited) + GetQueryDelimited(c *gin.Context, params GetQueryDelimitedParams) + + // (GET /queryForm) + GetQueryForm(c *gin.Context, params GetQueryFormParams) + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(c *gin.Context, param []int32) + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(c *gin.Context, param Object) + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(c *gin.Context, param int32) + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(c *gin.Context, param []int32) + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(c *gin.Context, param Object) + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(c *gin.Context, param int32) + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(c *gin.Context, n1param string) +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandler func(*gin.Context, error, int) +} + +type MiddlewareFunc func(c *gin.Context) + +// GetContentObject operation middleware +func (siw *ServerInterfaceWrapper) GetContentObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(c.Param("param")), ¶m) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Error unmarshaling parameter 'param' as JSON"), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetContentObject(c, param) +} + +// GetCookie operation middleware +func (siw *ServerInterfaceWrapper) GetCookie(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + { + var cookie string + + if cookie, err = c.Cookie("p"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter p: %w", err), http.StatusBadRequest) + return + } + params.P = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("ep"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ep: %w", err), http.StatusBadRequest) + return + } + params.Ep = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("ea"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ea: %w", err), http.StatusBadRequest) + return + } + params.Ea = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("a"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter a: %w", err), http.StatusBadRequest) + return + } + params.A = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("eo"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter eo: %w", err), http.StatusBadRequest) + return + } + params.Eo = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("o"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter o: %w", err), http.StatusBadRequest) + return + } + params.O = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("co"); err == nil { + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Error unescaping cookie parameter 'co'"), http.StatusBadRequest) + return + } + + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Error unmarshaling parameter 'co' as JSON"), http.StatusBadRequest) + return + } + + params.Co = &value + + } + } + + { + var cookie string + + if cookie, err = c.Cookie("1s"); err == nil { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter 1s: %w", err), http.StatusBadRequest) + return + } + params.N1s = &value + + } + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetCookie(c, params) +} + +// EnumParams operation middleware +func (siw *ServerInterfaceWrapper) EnumParams(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", c.Request.URL.Query(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter enumPathParam: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.EnumParams(c, params) +} + +// GetHeader operation middleware +func (siw *ServerInterfaceWrapper) GetHeader(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := c.Request.Header + + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Primitive, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Primitive: %w", err), http.StatusBadRequest) + return + } + + params.XPrimitive = &XPrimitive + + } + + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Primitive-Exploded, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Primitive-Exploded: %w", err), http.StatusBadRequest) + return + } + + params.XPrimitiveExploded = &XPrimitiveExploded + + } + + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Array-Exploded, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Array-Exploded: %w", err), http.StatusBadRequest) + return + } + + params.XArrayExploded = &XArrayExploded + + } + + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Array, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Array: %w", err), http.StatusBadRequest) + return + } + + params.XArray = &XArray + + } + + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Object-Exploded, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Object-Exploded: %w", err), http.StatusBadRequest) + return + } + + params.XObjectExploded = &XObjectExploded + + } + + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Object, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-Object: %w", err), http.StatusBadRequest) + return + } + + params.XObject = &XObject + + } + + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Complex-Object, got %d", n), http.StatusBadRequest) + return + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Error unmarshaling parameter 'X-Complex-Object' as JSON"), http.StatusBadRequest) + return + } + + params.XComplexObject = &XComplexObject + + } + + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for 1-Starting-With-Number, got %d", n), http.StatusBadRequest) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter 1-Starting-With-Number: %w", err), http.StatusBadRequest) + return + } + + params.N1StartingWithNumber = &N1StartingWithNumber + + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetHeader(c, params) +} + +// GetLabelExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelExplodeArray(c, param) +} + +// GetLabelExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelExplodeObject(c, param) +} + +// GetLabelExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodePrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelExplodePrimitive(c, param) +} + +// GetLabelNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelNoExplodeArray(c, param) +} + +// GetLabelNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelNoExplodeObject(c, param) +} + +// GetLabelPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelPrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetLabelPrimitive(c, param) +} + +// GetMatrixExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixExplodeArray(c, id) +} + +// GetMatrixExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixExplodeObject(c, id) +} + +// GetMatrixExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodePrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixExplodePrimitive(c, id) +} + +// GetMatrixNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixNoExplodeArray(c, id) +} + +// GetMatrixNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixNoExplodeObject(c, id) +} + +// GetMatrixPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixPrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetMatrixPrimitive(c, id) +} + +// GetPassThrough operation middleware +func (siw *ServerInterfaceWrapper) GetPassThrough(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param = c.Param("param") + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetPassThrough(c, param) +} + +// GetDeepObject operation middleware +func (siw *ServerInterfaceWrapper) GetDeepObject(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", c.Request.URL.Query(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter deepObj: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetDeepObject(c, params) +} + +// GetQueryDelimited operation middleware +func (siw *ServerInterfaceWrapper) GetQueryDelimited(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", c.Request.URL.Query(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter sa: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", c.Request.URL.Query(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter pa: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetQueryDelimited(c, params) +} + +// GetQueryForm operation middleware +func (siw *ServerInterfaceWrapper) GetQueryForm(c *gin.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", c.Request.URL.Query(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ea: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", c.Request.URL.Query(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter a: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", c.Request.URL.Query(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter eo: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", c.Request.URL.Query(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter o: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", c.Request.URL.Query(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ep: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", c.Request.URL.Query(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter p: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", c.Request.URL.Query(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ps: %w", err), http.StatusBadRequest) + return + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := c.Query("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Error unmarshaling parameter 'co' as JSON: %w", err), http.StatusBadRequest) + return + } + + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", c.Request.URL.Query(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter 1s: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetQueryForm(c, params) +} + +// GetSimpleExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimpleExplodeArray(c, param) +} + +// GetSimpleExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimpleExplodeObject(c, param) +} + +// GetSimpleExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodePrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimpleExplodePrimitive(c, param) +} + +// GetSimpleNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeArray(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimpleNoExplodeArray(c, param) +} + +// GetSimpleNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeObject(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimpleNoExplodeObject(c, param) +} + +// GetSimplePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimplePrimitive(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", c.Param("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter param: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetSimplePrimitive(c, param) +} + +// GetStartingWithNumber operation middleware +func (siw *ServerInterfaceWrapper) GetStartingWithNumber(c *gin.Context) { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = c.Param("1param") + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetStartingWithNumber(c, n1param) +} + +// GinServerOptions provides options for the Gin server. +type GinServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc + ErrorHandler func(*gin.Context, error, int) +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router gin.IRouter, si ServerInterface) { + RegisterHandlersWithOptions(router, si, GinServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) { + errorHandler := options.ErrorHandler + if errorHandler == nil { + errorHandler = func(c *gin.Context, err error, statusCode int) { + c.JSON(statusCode, gin.H{"msg": err.Error()}) + } + } + + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandler: errorHandler, + } + + router.GET(options.BaseURL+"/contentObject/:param", wrapper.GetContentObject) + router.GET(options.BaseURL+"/cookie", wrapper.GetCookie) + router.GET(options.BaseURL+"/enums", wrapper.EnumParams) + router.GET(options.BaseURL+"/header", wrapper.GetHeader) + router.GET(options.BaseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) + router.GET(options.BaseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) + router.GET(options.BaseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) + router.GET(options.BaseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) + router.GET(options.BaseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) + router.GET(options.BaseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) + router.GET(options.BaseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) + router.GET(options.BaseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) + router.GET(options.BaseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) + router.GET(options.BaseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) + router.GET(options.BaseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) + router.GET(options.BaseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) + router.GET(options.BaseURL+"/passThrough/:param", wrapper.GetPassThrough) + router.GET(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject) + router.GET(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited) + router.GET(options.BaseURL+"/queryForm", wrapper.GetQueryForm) + router.GET(options.BaseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) + router.GET(options.BaseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) + router.GET(options.BaseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) + router.GET(options.BaseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) + router.GET(options.BaseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) + router.GET(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + router.GET(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/gin/gen/types.gen.go b/internal/test/parameters/gin/gen/types.gen.go new file mode 100644 index 0000000000..e73bcb5083 --- /dev/null +++ b/internal/test/parameters/gin/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package ginparamsgen 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 ginparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/gin/server.cfg.yaml b/internal/test/parameters/gin/server.cfg.yaml new file mode 100644 index 0000000000..66fa6608ba --- /dev/null +++ b/internal/test/parameters/gin/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: ginparamsgen +generate: + gin-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/gin/server.go b/internal/test/parameters/gin/server.go new file mode 100644 index 0000000000..4f4184a0a9 --- /dev/null +++ b/internal/test/parameters/gin/server.go @@ -0,0 +1,44 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package ginparams + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gin/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func (s *Server) GetContentObject(c *gin.Context, param gen.ComplexObject) { c.JSON(http.StatusOK, param) } +func (s *Server) GetCookie(c *gin.Context, params gen.GetCookieParams) { c.JSON(http.StatusOK, params) } +func (s *Server) EnumParams(c *gin.Context, params gen.EnumParamsParams) { c.Status(http.StatusNoContent) } +func (s *Server) GetHeader(c *gin.Context, params gen.GetHeaderParams) { c.JSON(http.StatusOK, params) } +func (s *Server) GetLabelExplodeArray(c *gin.Context, param []int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodeObject(c *gin.Context, param gen.Object) { c.JSON(http.StatusOK, param) } +func (s *Server) GetLabelExplodePrimitive(c *gin.Context, param int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeArray(c *gin.Context, param []int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetLabelNoExplodeObject(c *gin.Context, param gen.Object) { c.JSON(http.StatusOK, param) } +func (s *Server) GetLabelPrimitive(c *gin.Context, param int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetMatrixExplodeArray(c *gin.Context, id []int32) { c.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodeObject(c *gin.Context, id gen.Object) { c.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixExplodePrimitive(c *gin.Context, id int32) { c.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeArray(c *gin.Context, id []int32) { c.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixNoExplodeObject(c *gin.Context, id gen.Object) { c.JSON(http.StatusOK, id) } +func (s *Server) GetMatrixPrimitive(c *gin.Context, id int32) { c.JSON(http.StatusOK, id) } +func (s *Server) GetPassThrough(c *gin.Context, param string) { c.JSON(http.StatusOK, param) } +func (s *Server) GetDeepObject(c *gin.Context, params gen.GetDeepObjectParams) { c.JSON(http.StatusOK, params) } +func (s *Server) GetQueryDelimited(c *gin.Context, params gen.GetQueryDelimitedParams) { c.JSON(http.StatusOK, params) } +func (s *Server) GetQueryForm(c *gin.Context, params gen.GetQueryFormParams) { c.JSON(http.StatusOK, params) } +func (s *Server) GetSimpleExplodeArray(c *gin.Context, param []int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodeObject(c *gin.Context, param gen.Object) { c.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleExplodePrimitive(c *gin.Context, param int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeArray(c *gin.Context, param []int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetSimpleNoExplodeObject(c *gin.Context, param gen.Object) { c.JSON(http.StatusOK, param) } +func (s *Server) GetSimplePrimitive(c *gin.Context, param int32) { c.JSON(http.StatusOK, param) } +func (s *Server) GetStartingWithNumber(c *gin.Context, n1param string) { c.JSON(http.StatusOK, n1param) } diff --git a/internal/test/parameters/gin/types.cfg.yaml b/internal/test/parameters/gin/types.cfg.yaml new file mode 100644 index 0000000000..3f7932b307 --- /dev/null +++ b/internal/test/parameters/gin/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: ginparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/gorilla/gen/server.gen.go b/internal/test/parameters/gorilla/gen/server.gen.go new file mode 100644 index 0000000000..b528089ecb --- /dev/null +++ b/internal/test/parameters/gorilla/gen/server.gen.go @@ -0,0 +1,1496 @@ +// Package gorillaparamsgen 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 gorillaparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/gorilla/mux" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(w http.ResponseWriter, r *http.Request, param ComplexObject) + + // (GET /cookie) + GetCookie(w http.ResponseWriter, r *http.Request, params GetCookieParams) + + // (GET /enums) + EnumParams(w http.ResponseWriter, r *http.Request, params EnumParamsParams) + + // (GET /header) + GetHeader(w http.ResponseWriter, r *http.Request, params GetHeaderParams) + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /passThrough/{param}) + GetPassThrough(w http.ResponseWriter, r *http.Request, param string) + + // (GET /queryDeepObject) + GetDeepObject(w http.ResponseWriter, r *http.Request, params GetDeepObjectParams) + + // (GET /queryDelimited) + GetQueryDelimited(w http.ResponseWriter, r *http.Request, params GetQueryDelimitedParams) + + // (GET /queryForm) + GetQueryForm(w http.ResponseWriter, r *http.Request, params GetQueryFormParams) + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) +} + +// 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 + +// GetContentObject operation middleware +func (siw *ServerInterfaceWrapper) GetContentObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(mux.Vars(r)["param"]), ¶m) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetContentObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetCookie operation middleware +func (siw *ServerInterfaceWrapper) GetCookie(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("p"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + return + } + params.P = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ep"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + return + } + params.Ep = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ea"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + return + } + params.Ea = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("a"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + return + } + params.A = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("eo"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + return + } + params.Eo = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("o"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + return + } + params.O = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("co"); err == nil { + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + err = fmt.Errorf("Error unescaping cookie parameter 'co'") + siw.ErrorHandlerFunc(w, r, &UnescapedCookieParamError{ParamName: "co", Err: err}) + return + } + + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("1s"); err == nil { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + return + } + params.N1s = &value + + } + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetCookie(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// EnumParams operation middleware +func (siw *ServerInterfaceWrapper) EnumParams(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", r.URL.Query(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "enumPathParam"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "enumPathParam", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.EnumParams(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetHeader operation middleware +func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := r.Header + + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive", Err: err}) + return + } + + params.XPrimitive = &XPrimitive + + } + + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive-Exploded", Err: err}) + return + } + + params.XPrimitiveExploded = &XPrimitiveExploded + + } + + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array-Exploded", Err: err}) + return + } + + params.XArrayExploded = &XArrayExploded + + } + + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array", Err: err}) + return + } + + params.XArray = &XArray + + } + + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object-Exploded", Err: err}) + return + } + + params.XObjectExploded = &XObjectExploded + + } + + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object", Err: err}) + return + } + + params.XObject = &XObject + + } + + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Complex-Object", Count: n}) + return + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "X-Complex-Object", Err: err}) + return + } + + params.XComplexObject = &XComplexObject + + } + + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "1-Starting-With-Number", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1-Starting-With-Number", Err: err}) + return + } + + params.N1StartingWithNumber = &N1StartingWithNumber + + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetHeader(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelPrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodePrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixPrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetPassThrough operation middleware +func (siw *ServerInterfaceWrapper) GetPassThrough(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param = mux.Vars(r)["param"] + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetPassThrough(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeepObject operation middleware +func (siw *ServerInterfaceWrapper) GetDeepObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", r.URL.Query(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "deepObj"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "deepObj", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeepObject(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryDelimited operation middleware +func (siw *ServerInterfaceWrapper) GetQueryDelimited(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", r.URL.Query(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "sa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "sa", Err: err}) + } + return + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", r.URL.Query(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "pa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "pa", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryDelimited(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryForm operation middleware +func (siw *ServerInterfaceWrapper) GetQueryForm(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", r.URL.Query(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ea"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + } + return + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", r.URL.Query(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "a"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + } + return + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", r.URL.Query(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "eo"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + } + return + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", r.URL.Query(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "o"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + } + return + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", r.URL.Query(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ep"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + } + return + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", r.URL.Query(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "p"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + } + return + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", r.URL.Query(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ps"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ps", Err: err}) + } + return + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := r.URL.Query().Get("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", r.URL.Query(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "1s"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryForm(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimplePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimplePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", mux.Vars(r)["param"], ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimplePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetStartingWithNumber operation middleware +func (siw *ServerInterfaceWrapper) GetStartingWithNumber(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = mux.Vars(r)["1param"] + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetStartingWithNumber(w, r, n1param) + })) + + 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, GorillaServerOptions{}) +} + +type GorillaServerOptions struct { + BaseURL string + BaseRouter *mux.Router + 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, r *mux.Router) http.Handler { + return HandlerWithOptions(si, GorillaServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r *mux.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, GorillaServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = mux.NewRouter() + } + 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, + } + + r.HandleFunc(options.BaseURL+"/contentObject/{param}", wrapper.GetContentObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/cookie", wrapper.GetCookie).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/enums", wrapper.EnumParams).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/header", wrapper.GetHeader).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelExplodeArray/{param}", wrapper.GetLabelExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelExplodeObject/{param}", wrapper.GetLabelExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelExplodePrimitive/{param}", wrapper.GetLabelExplodePrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelNoExplodeArray/{param}", wrapper.GetLabelNoExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelNoExplodeObject/{param}", wrapper.GetLabelNoExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/labelPrimitive/{param}", wrapper.GetLabelPrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixExplodeArray/{id}", wrapper.GetMatrixExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixExplodeObject/{id}", wrapper.GetMatrixExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixExplodePrimitive/{id}", wrapper.GetMatrixExplodePrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixNoExplodeArray/{id}", wrapper.GetMatrixNoExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixNoExplodeObject/{id}", wrapper.GetMatrixNoExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/matrixPrimitive/{id}", wrapper.GetMatrixPrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/passThrough/{param}", wrapper.GetPassThrough).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/queryForm", wrapper.GetQueryForm).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simpleExplodeArray/{param}", wrapper.GetSimpleExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simpleExplodeObject/{param}", wrapper.GetSimpleExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simpleExplodePrimitive/{param}", wrapper.GetSimpleExplodePrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simpleNoExplodeArray/{param}", wrapper.GetSimpleNoExplodeArray).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simpleNoExplodeObject/{param}", wrapper.GetSimpleNoExplodeObject).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/simplePrimitive/{param}", wrapper.GetSimplePrimitive).Methods(http.MethodGet) + + r.HandleFunc(options.BaseURL+"/startingWithNumber/{1param}", wrapper.GetStartingWithNumber).Methods(http.MethodGet) + + return r +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/gorilla/gen/types.gen.go b/internal/test/parameters/gorilla/gen/types.gen.go new file mode 100644 index 0000000000..b7a27e4096 --- /dev/null +++ b/internal/test/parameters/gorilla/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package gorillaparamsgen 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 gorillaparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/gorilla/server.cfg.yaml b/internal/test/parameters/gorilla/server.cfg.yaml new file mode 100644 index 0000000000..cf492d30ec --- /dev/null +++ b/internal/test/parameters/gorilla/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: gorillaparamsgen +generate: + gorilla-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/gorilla/server.go b/internal/test/parameters/gorilla/server.go new file mode 100644 index 0000000000..afdde25e25 --- /dev/null +++ b/internal/test/parameters/gorilla/server.go @@ -0,0 +1,48 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package gorillaparams + +import ( + "encoding/json" + "net/http" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gorilla/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func writeJSON(w http.ResponseWriter, v interface{}) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(v) +} + +func (s *Server) GetContentObject(w http.ResponseWriter, r *http.Request, param gen.ComplexObject) { writeJSON(w, param) } +func (s *Server) GetCookie(w http.ResponseWriter, r *http.Request, params gen.GetCookieParams) { writeJSON(w, params) } +func (s *Server) EnumParams(w http.ResponseWriter, r *http.Request, params gen.EnumParamsParams) { w.WriteHeader(http.StatusNoContent) } +func (s *Server) GetHeader(w http.ResponseWriter, r *http.Request, params gen.GetHeaderParams) { writeJSON(w, params) } +func (s *Server) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetPassThrough(w http.ResponseWriter, r *http.Request, param string) { writeJSON(w, param) } +func (s *Server) GetDeepObject(w http.ResponseWriter, r *http.Request, params gen.GetDeepObjectParams) { writeJSON(w, params) } +func (s *Server) GetQueryDelimited(w http.ResponseWriter, r *http.Request, params gen.GetQueryDelimitedParams) { writeJSON(w, params) } +func (s *Server) GetQueryForm(w http.ResponseWriter, r *http.Request, params gen.GetQueryFormParams) { writeJSON(w, params) } +func (s *Server) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) { writeJSON(w, n1param) } diff --git a/internal/test/parameters/gorilla/types.cfg.yaml b/internal/test/parameters/gorilla/types.cfg.yaml new file mode 100644 index 0000000000..9e2fcd7c3b --- /dev/null +++ b/internal/test/parameters/gorilla/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: gorillaparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/iris/gen/server.gen.go b/internal/test/parameters/iris/gen/server.gen.go new file mode 100644 index 0000000000..eff396ab5a --- /dev/null +++ b/internal/test/parameters/iris/gen/server.gen.go @@ -0,0 +1,1132 @@ +// Package irisparamsgen 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 irisparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/kataras/iris/v12" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(ctx iris.Context, param ComplexObject) + + // (GET /cookie) + GetCookie(ctx iris.Context, params GetCookieParams) + + // (GET /enums) + EnumParams(ctx iris.Context, params EnumParamsParams) + + // (GET /header) + GetHeader(ctx iris.Context, params GetHeaderParams) + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(ctx iris.Context, param []int32) + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(ctx iris.Context, param Object) + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(ctx iris.Context, param int32) + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(ctx iris.Context, param []int32) + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(ctx iris.Context, param Object) + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(ctx iris.Context, param int32) + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(ctx iris.Context, id []int32) + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(ctx iris.Context, id Object) + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(ctx iris.Context, id int32) + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(ctx iris.Context, id []int32) + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(ctx iris.Context, id Object) + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(ctx iris.Context, id int32) + + // (GET /passThrough/{param}) + GetPassThrough(ctx iris.Context, param string) + + // (GET /queryDeepObject) + GetDeepObject(ctx iris.Context, params GetDeepObjectParams) + + // (GET /queryDelimited) + GetQueryDelimited(ctx iris.Context, params GetQueryDelimitedParams) + + // (GET /queryForm) + GetQueryForm(ctx iris.Context, params GetQueryFormParams) + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(ctx iris.Context, param []int32) + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(ctx iris.Context, param Object) + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(ctx iris.Context, param int32) + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(ctx iris.Context, param []int32) + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(ctx iris.Context, param Object) + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(ctx iris.Context, param int32) + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(ctx iris.Context, n1param string) +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +type MiddlewareFunc iris.Handler + +// GetContentObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetContentObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(ctx.Params().Get("param")), ¶m) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.WriteString("Error unmarshaling parameter 'param' as JSON") + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetContentObject(ctx, param) +} + +// GetCookie converts iris context to params. +func (w *ServerInterfaceWrapper) GetCookie(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + if cookie := ctx.GetCookie("p"); cookie != "" { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter p: %s", err) + return + } + params.P = &value + + } + + if cookie := ctx.GetCookie("ep"); cookie != "" { + + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter ep: %s", err) + return + } + params.Ep = &value + + } + + if cookie := ctx.GetCookie("ea"); cookie != "" { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter ea: %s", err) + return + } + params.Ea = &value + + } + + if cookie := ctx.GetCookie("a"); cookie != "" { + + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter a: %s", err) + return + } + params.A = &value + + } + + if cookie := ctx.GetCookie("eo"); cookie != "" { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter eo: %s", err) + return + } + params.Eo = &value + + } + + if cookie := ctx.GetCookie("o"); cookie != "" { + + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter o: %s", err) + return + } + params.O = &value + + } + + if cookie := ctx.GetCookie("co"); cookie != "" { + + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.WriteString("Error unescaping cookie parameter 'co'") + return + } + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.WriteString("Error unmarshaling parameter 'co' as JSON") + return + } + params.Co = &value + + } + + if cookie := ctx.GetCookie("1s"); cookie != "" { + + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter 1s: %s", err) + return + } + params.N1s = &value + + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetCookie(ctx, params) +} + +// EnumParams converts iris context to params. +func (w *ServerInterfaceWrapper) EnumParams(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", ctx.Request().URL.Query(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter enumPathParam: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.EnumParams(ctx, params) +} + +// GetHeader converts iris context to params. +func (w *ServerInterfaceWrapper) GetHeader(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := ctx.Request().Header + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Primitive, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Primitive: %s", err) + return + } + + params.XPrimitive = &XPrimitive + } + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Primitive-Exploded, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Primitive-Exploded: %s", err) + return + } + + params.XPrimitiveExploded = &XPrimitiveExploded + } + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Array-Exploded, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Array-Exploded: %s", err) + return + } + + params.XArrayExploded = &XArrayExploded + } + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Array, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Array: %s", err) + return + } + + params.XArray = &XArray + } + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Object-Exploded, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Object-Exploded: %s", err) + return + } + + params.XObjectExploded = &XObjectExploded + } + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Object, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter X-Object: %s", err) + return + } + + params.XObject = &XObject + } + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Complex-Object, got %d", n) + return + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.WriteString("Error unmarshaling parameter 'X-Complex-Object' as JSON") + return + } + + params.XComplexObject = &XComplexObject + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for 1-Starting-With-Number, got %d", n) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter 1-Starting-With-Number: %s", err) + return + } + + params.N1StartingWithNumber = &N1StartingWithNumber + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetHeader(ctx, params) +} + +// GetLabelExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelExplodeArray(ctx, param) +} + +// GetLabelExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelExplodeObject(ctx, param) +} + +// GetLabelExplodePrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelExplodePrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelExplodePrimitive(ctx, param) +} + +// GetLabelNoExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelNoExplodeArray(ctx, param) +} + +// GetLabelNoExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelNoExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelNoExplodeObject(ctx, param) +} + +// GetLabelPrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetLabelPrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetLabelPrimitive(ctx, param) +} + +// GetMatrixExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixExplodeArray(ctx, id) +} + +// GetMatrixExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixExplodeObject(ctx, id) +} + +// GetMatrixExplodePrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixExplodePrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixExplodePrimitive(ctx, id) +} + +// GetMatrixNoExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixNoExplodeArray(ctx, id) +} + +// GetMatrixNoExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixNoExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixNoExplodeObject(ctx, id) +} + +// GetMatrixPrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetMatrixPrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter id: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetMatrixPrimitive(ctx, id) +} + +// GetPassThrough converts iris context to params. +func (w *ServerInterfaceWrapper) GetPassThrough(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param = ctx.Params().Get("param") + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetPassThrough(ctx, param) +} + +// GetDeepObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetDeepObject(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", ctx.Request().URL.Query(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter deepObj: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetDeepObject(ctx, params) +} + +// GetQueryDelimited converts iris context to params. +func (w *ServerInterfaceWrapper) GetQueryDelimited(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", ctx.Request().URL.Query(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter sa: %s", err) + return + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", ctx.Request().URL.Query(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter pa: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetQueryDelimited(ctx, params) +} + +// GetQueryForm converts iris context to params. +func (w *ServerInterfaceWrapper) GetQueryForm(ctx iris.Context) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", ctx.Request().URL.Query(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter ea: %s", err) + return + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", ctx.Request().URL.Query(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter a: %s", err) + return + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", ctx.Request().URL.Query(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter eo: %s", err) + return + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", ctx.Request().URL.Query(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter o: %s", err) + return + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", ctx.Request().URL.Query(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter ep: %s", err) + return + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", ctx.Request().URL.Query(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter p: %s", err) + return + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", ctx.Request().URL.Query(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter ps: %s", err) + return + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := ctx.URLParam("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.WriteString("Error unmarshaling parameter 'co' as JSON") + return + } + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", ctx.Request().URL.Query(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter 1s: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetQueryForm(ctx, params) +} + +// GetSimpleExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimpleExplodeArray(ctx, param) +} + +// GetSimpleExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimpleExplodeObject(ctx, param) +} + +// GetSimpleExplodePrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimpleExplodePrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimpleExplodePrimitive(ctx, param) +} + +// GetSimpleNoExplodeArray converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeArray(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimpleNoExplodeArray(ctx, param) +} + +// GetSimpleNoExplodeObject converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimpleNoExplodeObject(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimpleNoExplodeObject(ctx, param) +} + +// GetSimplePrimitive converts iris context to params. +func (w *ServerInterfaceWrapper) GetSimplePrimitive(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", ctx.Params().Get("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Invalid format for parameter param: %s", err) + return + } + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetSimplePrimitive(ctx, param) +} + +// GetStartingWithNumber converts iris context to params. +func (w *ServerInterfaceWrapper) GetStartingWithNumber(ctx iris.Context) { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = ctx.Params().Get("1param") + + // Invoke the callback with all the unmarshaled arguments + w.Handler.GetStartingWithNumber(ctx, n1param) +} + +// IrisServerOption is the option for iris server +type IrisServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router *iris.Application, si ServerInterface) { + RegisterHandlersWithOptions(router, si, IrisServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.Get(options.BaseURL+"/contentObject/:param", wrapper.GetContentObject) + router.Get(options.BaseURL+"/cookie", wrapper.GetCookie) + router.Get(options.BaseURL+"/enums", wrapper.EnumParams) + router.Get(options.BaseURL+"/header", wrapper.GetHeader) + router.Get(options.BaseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) + router.Get(options.BaseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) + router.Get(options.BaseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) + router.Get(options.BaseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) + router.Get(options.BaseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) + router.Get(options.BaseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) + router.Get(options.BaseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) + router.Get(options.BaseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) + router.Get(options.BaseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) + router.Get(options.BaseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) + router.Get(options.BaseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) + router.Get(options.BaseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) + router.Get(options.BaseURL+"/passThrough/:param", wrapper.GetPassThrough) + router.Get(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject) + router.Get(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited) + router.Get(options.BaseURL+"/queryForm", wrapper.GetQueryForm) + router.Get(options.BaseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) + router.Get(options.BaseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) + router.Get(options.BaseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) + router.Get(options.BaseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) + router.Get(options.BaseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) + router.Get(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + router.Get(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + + router.Build() +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/iris/gen/types.gen.go b/internal/test/parameters/iris/gen/types.gen.go new file mode 100644 index 0000000000..b075b62ba0 --- /dev/null +++ b/internal/test/parameters/iris/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package irisparamsgen 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 irisparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/iris/server.cfg.yaml b/internal/test/parameters/iris/server.cfg.yaml new file mode 100644 index 0000000000..3b1099ea5b --- /dev/null +++ b/internal/test/parameters/iris/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: irisparamsgen +generate: + iris-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/iris/server.go b/internal/test/parameters/iris/server.go new file mode 100644 index 0000000000..4d63b96242 --- /dev/null +++ b/internal/test/parameters/iris/server.go @@ -0,0 +1,44 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package irisparams + +import ( + "net/http" + + "github.com/kataras/iris/v12" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/iris/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func (s *Server) GetContentObject(ctx iris.Context, param gen.ComplexObject) { _ = ctx.JSON(param) } +func (s *Server) GetCookie(ctx iris.Context, params gen.GetCookieParams) { _ = ctx.JSON(params) } +func (s *Server) EnumParams(ctx iris.Context, params gen.EnumParamsParams) { ctx.StatusCode(http.StatusNoContent) } +func (s *Server) GetHeader(ctx iris.Context, params gen.GetHeaderParams) { _ = ctx.JSON(params) } +func (s *Server) GetLabelExplodeArray(ctx iris.Context, param []int32) { _ = ctx.JSON(param) } +func (s *Server) GetLabelExplodeObject(ctx iris.Context, param gen.Object) { _ = ctx.JSON(param) } +func (s *Server) GetLabelExplodePrimitive(ctx iris.Context, param int32) { _ = ctx.JSON(param) } +func (s *Server) GetLabelNoExplodeArray(ctx iris.Context, param []int32) { _ = ctx.JSON(param) } +func (s *Server) GetLabelNoExplodeObject(ctx iris.Context, param gen.Object) { _ = ctx.JSON(param) } +func (s *Server) GetLabelPrimitive(ctx iris.Context, param int32) { _ = ctx.JSON(param) } +func (s *Server) GetMatrixExplodeArray(ctx iris.Context, id []int32) { _ = ctx.JSON(id) } +func (s *Server) GetMatrixExplodeObject(ctx iris.Context, id gen.Object) { _ = ctx.JSON(id) } +func (s *Server) GetMatrixExplodePrimitive(ctx iris.Context, id int32) { _ = ctx.JSON(id) } +func (s *Server) GetMatrixNoExplodeArray(ctx iris.Context, id []int32) { _ = ctx.JSON(id) } +func (s *Server) GetMatrixNoExplodeObject(ctx iris.Context, id gen.Object) { _ = ctx.JSON(id) } +func (s *Server) GetMatrixPrimitive(ctx iris.Context, id int32) { _ = ctx.JSON(id) } +func (s *Server) GetPassThrough(ctx iris.Context, param string) { _ = ctx.JSON(param) } +func (s *Server) GetDeepObject(ctx iris.Context, params gen.GetDeepObjectParams) { _ = ctx.JSON(params) } +func (s *Server) GetQueryDelimited(ctx iris.Context, params gen.GetQueryDelimitedParams) { _ = ctx.JSON(params) } +func (s *Server) GetQueryForm(ctx iris.Context, params gen.GetQueryFormParams) { _ = ctx.JSON(params) } +func (s *Server) GetSimpleExplodeArray(ctx iris.Context, param []int32) { _ = ctx.JSON(param) } +func (s *Server) GetSimpleExplodeObject(ctx iris.Context, param gen.Object) { _ = ctx.JSON(param) } +func (s *Server) GetSimpleExplodePrimitive(ctx iris.Context, param int32) { _ = ctx.JSON(param) } +func (s *Server) GetSimpleNoExplodeArray(ctx iris.Context, param []int32) { _ = ctx.JSON(param) } +func (s *Server) GetSimpleNoExplodeObject(ctx iris.Context, param gen.Object) { _ = ctx.JSON(param) } +func (s *Server) GetSimplePrimitive(ctx iris.Context, param int32) { _ = ctx.JSON(param) } +func (s *Server) GetStartingWithNumber(ctx iris.Context, n1param string) { _ = ctx.JSON(n1param) } diff --git a/internal/test/parameters/iris/types.cfg.yaml b/internal/test/parameters/iris/types.cfg.yaml new file mode 100644 index 0000000000..ffb12605ab --- /dev/null +++ b/internal/test/parameters/iris/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: irisparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/parameters/param_roundtrip_test.go b/internal/test/parameters/param_roundtrip_test.go new file mode 100644 index 0000000000..e0b2fc93d1 --- /dev/null +++ b/internal/test/parameters/param_roundtrip_test.go @@ -0,0 +1,517 @@ +package parameters_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/go-chi/chi/v5" + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/adaptor" + "github.com/gorilla/mux" + "github.com/kataras/iris/v12" + "github.com/labstack/echo/v4" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + chiparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/chi" + chigen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/chi/gen" + paramclient "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/client/gen" + echoparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/echo" + echogen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/echo/gen" + fiberparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/fiber" + fibergen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/fiber/gen" + ginparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gin" + gingen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gin/gen" + gorillaparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gorilla" + gorillgen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/gorilla/gen" + irisparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/iris" + irisgen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/iris/gen" + stdhttpparams "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/stdhttp" + stdhttpgen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/stdhttp/gen" +) + +func TestEchoParameterRoundTrip(t *testing.T) { + var s echoparams.Server + e := echo.New() + echogen.RegisterHandlers(e, &s) + testImpl(t, e) +} + +func TestChiParameterRoundTrip(t *testing.T) { + var s chiparams.Server + r := chi.NewRouter() + handler := chigen.HandlerFromMux(&s, r) + testImpl(t, handler) +} + +func TestGinParameterRoundTrip(t *testing.T) { + var s ginparams.Server + gin.SetMode(gin.ReleaseMode) + r := gin.New() + gingen.RegisterHandlers(r, &s) + testImpl(t, r) +} + +func TestGorillaParameterRoundTrip(t *testing.T) { + var s gorillaparams.Server + r := mux.NewRouter() + handler := gorillgen.HandlerFromMux(&s, r) + testImpl(t, handler) +} + +func TestIrisParameterRoundTrip(t *testing.T) { + var s irisparams.Server + app := iris.New() + irisgen.RegisterHandlers(app, &s) + testImpl(t, app) +} + +func TestFiberParameterRoundTrip(t *testing.T) { + var s fiberparams.Server + app := fiber.New() + fibergen.RegisterHandlers(app, &s) + testImpl(t, adaptor.FiberApp(app)) +} + +func TestStdHttpParameterRoundTrip(t *testing.T) { + // The OpenAPI spec includes a path parameter named "1param" which starts + // with a digit. Go's stdlib ServeMux requires wildcard names to be valid + // Go identifiers, so registering this route panics. This is a known + // stdhttp panics because net/http.ServeMux rejects wildcard names + // starting with a digit ("1param"). Skip until codegen sanitizes the name. + t.Skip("stdhttp panics on path param name starting with digit (1param) — see #2306") + var s stdhttpparams.Server + handler := stdhttpgen.Handler(&s) + testImpl(t, handler) +} + +// testImpl runs the full parameter roundtrip test suite against any http.Handler. +// The generated client serializes Go values into an HTTP request, the server +// deserializes them and echoes them back as JSON, and we compare the response +// body against the original values. +func testImpl(t *testing.T, handler http.Handler) { + t.Helper() + + server := "http://example.com" + + expectedObject := paramclient.Object{ + FirstName: "Alex", + Role: "admin", + } + + expectedComplexObject := paramclient.ComplexObject{ + Object: expectedObject, + Id: 12345, + IsAdmin: true, + } + + expectedArray := []int32{3, 4, 5} + + var expectedPrimitive int32 = 5 + + // doRoundTrip sends a request to the handler, asserts 200, and decodes the JSON response. + doRoundTrip := func(t *testing.T, req *http.Request, target interface{}) { + t.Helper() + // The generated client produces requests via http.NewRequest which + // leaves RequestURI empty. Some adapters (notably Fiber) need it + // set to route correctly. + req.RequestURI = req.URL.RequestURI() + rec := httptest.NewRecorder() + handler.ServeHTTP(rec, req) + if !assert.Equal(t, http.StatusOK, rec.Code, "server returned %d; body: %s", rec.Code, rec.Body.String()) { + return + } + if target != nil { + require.NoError(t, json.NewDecoder(rec.Body).Decode(target), "failed to decode response body") + } + } + + // ========================================================================= + // Path Parameters + // ========================================================================= + t.Run("path", func(t *testing.T) { + t.Run("simple", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := paramclient.NewGetSimplePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("primitive explode", func(t *testing.T) { + req, err := paramclient.NewGetSimpleExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("array noExplode", func(t *testing.T) { + req, err := paramclient.NewGetSimpleNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("array explode", func(t *testing.T) { + req, err := paramclient.NewGetSimpleExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("object noExplode", func(t *testing.T) { + req, err := paramclient.NewGetSimpleNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + + t.Run("object explode", func(t *testing.T) { + req, err := paramclient.NewGetSimpleExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + + t.Run("label", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := paramclient.NewGetLabelPrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("primitive explode", func(t *testing.T) { + req, err := paramclient.NewGetLabelExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("array noExplode", func(t *testing.T) { + req, err := paramclient.NewGetLabelNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("array explode", func(t *testing.T) { + req, err := paramclient.NewGetLabelExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("object noExplode", func(t *testing.T) { + req, err := paramclient.NewGetLabelNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + + t.Run("object explode", func(t *testing.T) { + req, err := paramclient.NewGetLabelExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + + t.Run("matrix", func(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + req, err := paramclient.NewGetMatrixPrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("primitive explode", func(t *testing.T) { + req, err := paramclient.NewGetMatrixExplodePrimitiveRequest(server, expectedPrimitive) + require.NoError(t, err) + var got int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedPrimitive, got) + }) + + t.Run("array noExplode", func(t *testing.T) { + req, err := paramclient.NewGetMatrixNoExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("array explode", func(t *testing.T) { + req, err := paramclient.NewGetMatrixExplodeArrayRequest(server, expectedArray) + require.NoError(t, err) + var got []int32 + doRoundTrip(t, req, &got) + assert.Equal(t, expectedArray, got) + }) + + t.Run("object noExplode", func(t *testing.T) { + req, err := paramclient.NewGetMatrixNoExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + + t.Run("object explode", func(t *testing.T) { + req, err := paramclient.NewGetMatrixExplodeObjectRequest(server, expectedObject) + require.NoError(t, err) + var got paramclient.Object + doRoundTrip(t, req, &got) + assert.Equal(t, expectedObject, got) + }) + }) + + t.Run("content-based", func(t *testing.T) { + t.Run("json complex object", func(t *testing.T) { + req, err := paramclient.NewGetContentObjectRequest(server, expectedComplexObject) + require.NoError(t, err) + var got paramclient.ComplexObject + doRoundTrip(t, req, &got) + assert.Equal(t, expectedComplexObject, got) + }) + + t.Run("passthrough string", func(t *testing.T) { + req, err := paramclient.NewGetPassThroughRequest(server, "hello world") + require.NoError(t, err) + var got string + doRoundTrip(t, req, &got) + assert.Equal(t, "hello world", got) + }) + }) + }) + + // ========================================================================= + // Query Parameters + // ========================================================================= + t.Run("query", func(t *testing.T) { + t.Run("form", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := paramclient.Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedPrimitiveString = "123;456" + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := paramclient.GetQueryFormParams{ + Ea: &expectedArray, + A: &expectedArray2, + Eo: &expectedObject, + O: &expectedObject2, + Ep: &expectedPrimitive, + P: &expectedPrimitive2, + Ps: &expectedPrimitiveString, + Co: &expectedComplexObject, + N1s: &expectedN1s, + } + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + + t.Run("exploded array only", func(t *testing.T) { + params := paramclient.GetQueryFormParams{Ea: &expectedArray} + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Ea) + assert.Equal(t, expectedArray, *got.Ea) + }) + + t.Run("unexploded array only", func(t *testing.T) { + params := paramclient.GetQueryFormParams{A: &expectedArray} + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.A) + assert.Equal(t, expectedArray, *got.A) + }) + + t.Run("exploded object only", func(t *testing.T) { + params := paramclient.GetQueryFormParams{Eo: &expectedObject} + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Eo) + assert.Equal(t, expectedObject, *got.Eo) + }) + + t.Run("unexploded object only", func(t *testing.T) { + params := paramclient.GetQueryFormParams{O: &expectedObject} + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.O) + assert.Equal(t, expectedObject, *got.O) + }) + + t.Run("primitive with semicolon", func(t *testing.T) { + params := paramclient.GetQueryFormParams{Ps: &expectedPrimitiveString} + req, err := paramclient.NewGetQueryFormRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetQueryFormParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.Ps) + assert.Equal(t, expectedPrimitiveString, *got.Ps) + }) + }) + + t.Run("deepObject", func(t *testing.T) { + params := paramclient.GetDeepObjectParams{DeepObj: expectedComplexObject} + req, err := paramclient.NewGetDeepObjectRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetDeepObjectParams + doRoundTrip(t, req, &got) + assert.Equal(t, expectedComplexObject, got.DeepObj) + }) + + t.Run("spaceDelimited", func(t *testing.T) { + }) + + t.Run("pipeDelimited", func(t *testing.T) { + }) + }) + + // ========================================================================= + // Header Parameters + // ========================================================================= + t.Run("header", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := paramclient.Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := paramclient.GetHeaderParams{ + XPrimitive: &expectedPrimitive2, + XPrimitiveExploded: &expectedPrimitive, + XArrayExploded: &expectedArray, + XArray: &expectedArray2, + XObjectExploded: &expectedObject, + XObject: &expectedObject2, + XComplexObject: &expectedComplexObject, + N1StartingWithNumber: &expectedN1s, + } + req, err := paramclient.NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetHeaderParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + + t.Run("primitive only", func(t *testing.T) { + params := paramclient.GetHeaderParams{XPrimitive: &expectedPrimitive} + req, err := paramclient.NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XPrimitive) + assert.Equal(t, expectedPrimitive, *got.XPrimitive) + }) + + t.Run("array only", func(t *testing.T) { + params := paramclient.GetHeaderParams{XArray: &expectedArray} + req, err := paramclient.NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XArray) + assert.Equal(t, expectedArray, *got.XArray) + }) + + t.Run("object only", func(t *testing.T) { + params := paramclient.GetHeaderParams{XObject: &expectedObject} + req, err := paramclient.NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XObject) + assert.Equal(t, expectedObject, *got.XObject) + }) + }) + + // ========================================================================= + // Cookie Parameters + // ========================================================================= + t.Run("cookie", func(t *testing.T) { + expectedArray2 := []int32{6, 7, 8} + expectedObject2 := paramclient.Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} + var expectedPrimitive2 int32 = 100 + var expectedN1s = "111" + + t.Run("all params at once", func(t *testing.T) { + params := paramclient.GetCookieParams{ + P: &expectedPrimitive2, + Ep: &expectedPrimitive, + Ea: &expectedArray, + A: &expectedArray2, + Eo: &expectedObject, + O: &expectedObject2, + Co: &expectedComplexObject, + N1s: &expectedN1s, + } + req, err := paramclient.NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetCookieParams + doRoundTrip(t, req, &got) + assert.EqualValues(t, params, got) + }) + + t.Run("primitive only", func(t *testing.T) { + params := paramclient.GetCookieParams{P: &expectedPrimitive} + req, err := paramclient.NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.P) + assert.Equal(t, expectedPrimitive, *got.P) + }) + + t.Run("array only", func(t *testing.T) { + params := paramclient.GetCookieParams{A: &expectedArray} + req, err := paramclient.NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.A) + assert.Equal(t, expectedArray, *got.A) + }) + + t.Run("object only", func(t *testing.T) { + params := paramclient.GetCookieParams{O: &expectedObject} + req, err := paramclient.NewGetCookieRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetCookieParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.O) + assert.Equal(t, expectedObject, *got.O) + }) + }) +} diff --git a/internal/test/parameters/parameters.yaml b/internal/test/parameters/parameters.yaml index 682af6ab17..7c09631965 100644 --- a/internal/test/parameters/parameters.yaml +++ b/internal/test/parameters/parameters.yaml @@ -207,6 +207,81 @@ paths: responses: '200': $ref: "#/components/responses/SimpleResponse" + /simpleExplodePrimitive/{param}: + get: + operationId: getSimpleExplodePrimitive + parameters: + - name: param + in: path + required: true + style: simple + explode: true + schema: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" + /labelPrimitive/{.param}: + get: + operationId: getLabelPrimitive + parameters: + - name: param + in: path + required: true + style: label + explode: false + schema: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" + /labelExplodePrimitive/{.param*}: + get: + operationId: getLabelExplodePrimitive + parameters: + - name: param + in: path + required: true + style: label + explode: true + schema: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" + /matrixPrimitive/{;id}: + get: + operationId: getMatrixPrimitive + parameters: + - name: id + in: path + required: true + style: matrix + explode: false + schema: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" + /matrixExplodePrimitive/{;id*}: + get: + operationId: getMatrixExplodePrimitive + parameters: + - name: id + in: path + required: true + style: matrix + explode: true + schema: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" /contentObject/{param}: get: operationId: getContentObject @@ -328,6 +403,35 @@ paths: responses: '200': $ref: "#/components/responses/SimpleResponse" + /queryDelimited: + get: + operationId: getQueryDelimited + parameters: + - name: sa + description: space delimited array + in: query + required: false + style: spaceDelimited + explode: false + schema: + type: array + items: + type: integer + format: int32 + - name: pa + description: pipe delimited array + in: query + required: false + style: pipeDelimited + explode: false + schema: + type: array + items: + type: integer + format: int32 + responses: + '200': + $ref: "#/components/responses/SimpleResponse" /queryDeepObject: get: operationId: getDeepObject diff --git a/internal/test/parameters/stdhttp/gen/server.gen.go b/internal/test/parameters/stdhttp/gen/server.gen.go new file mode 100644 index 0000000000..520bb3ea46 --- /dev/null +++ b/internal/test/parameters/stdhttp/gen/server.gen.go @@ -0,0 +1,1478 @@ +//go:build go1.22 + +// Package stdhttpparamsgen 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 stdhttpparamsgen + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /contentObject/{param}) + GetContentObject(w http.ResponseWriter, r *http.Request, param ComplexObject) + + // (GET /cookie) + GetCookie(w http.ResponseWriter, r *http.Request, params GetCookieParams) + + // (GET /enums) + EnumParams(w http.ResponseWriter, r *http.Request, params EnumParamsParams) + + // (GET /header) + GetHeader(w http.ResponseWriter, r *http.Request, params GetHeaderParams) + + // (GET /labelExplodeArray/{.param*}) + GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelExplodeObject/{.param*}) + GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelExplodePrimitive/{.param*}) + GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /labelNoExplodeArray/{.param}) + GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /labelNoExplodeObject/{.param}) + GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /labelPrimitive/{.param}) + GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /matrixExplodeArray/{.id*}) + GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixExplodeObject/{.id*}) + GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixExplodePrimitive/{;id*}) + GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /matrixNoExplodeArray/{.id}) + GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) + + // (GET /matrixNoExplodeObject/{.id}) + GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id Object) + + // (GET /matrixPrimitive/{;id}) + GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) + + // (GET /passThrough/{param}) + GetPassThrough(w http.ResponseWriter, r *http.Request, param string) + + // (GET /queryDeepObject) + GetDeepObject(w http.ResponseWriter, r *http.Request, params GetDeepObjectParams) + + // (GET /queryDelimited) + GetQueryDelimited(w http.ResponseWriter, r *http.Request, params GetQueryDelimitedParams) + + // (GET /queryForm) + GetQueryForm(w http.ResponseWriter, r *http.Request, params GetQueryFormParams) + + // (GET /simpleExplodeArray/{param*}) + GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleExplodeObject/{param*}) + GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simpleExplodePrimitive/{param}) + GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /simpleNoExplodeArray/{param}) + GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) + + // (GET /simpleNoExplodeObject/{param}) + GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param Object) + + // (GET /simplePrimitive/{param}) + GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) + + // (GET /startingWithNumber/{1param}) + GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) +} + +// 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 + +// GetContentObject operation middleware +func (siw *ServerInterfaceWrapper) GetContentObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param ComplexObject + + err = json.Unmarshal([]byte(r.PathValue("param")), ¶m) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetContentObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetCookie operation middleware +func (siw *ServerInterfaceWrapper) GetCookie(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetCookieParams + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("p"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "p", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + return + } + params.P = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ep"); err == nil { + var value int32 + err = runtime.BindStyledParameterWithOptions("simple", "ep", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + return + } + params.Ep = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("ea"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "ea", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + return + } + params.Ea = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("a"); err == nil { + var value []int32 + err = runtime.BindStyledParameterWithOptions("simple", "a", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + return + } + params.A = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("eo"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "eo", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + return + } + params.Eo = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("o"); err == nil { + var value Object + err = runtime.BindStyledParameterWithOptions("simple", "o", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + return + } + params.O = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("co"); err == nil { + var value ComplexObject + var decoded string + decoded, err := url.QueryUnescape(cookie.Value) + if err != nil { + err = fmt.Errorf("Error unescaping cookie parameter 'co'") + siw.ErrorHandlerFunc(w, r, &UnescapedCookieParamError{ParamName: "co", Err: err}) + return + } + + err = json.Unmarshal([]byte(decoded), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + } + + { + var cookie *http.Cookie + + if cookie, err = r.Cookie("1s"); err == nil { + var value string + err = runtime.BindStyledParameterWithOptions("simple", "1s", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: true, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + return + } + params.N1s = &value + + } + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetCookie(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// EnumParams operation middleware +func (siw *ServerInterfaceWrapper) EnumParams(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params EnumParamsParams + + // ------------- Optional query parameter "enumPathParam" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "enumPathParam", r.URL.Query(), ¶ms.EnumPathParam, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "enumPathParam"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "enumPathParam", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.EnumParams(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetHeader operation middleware +func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetHeaderParams + + headers := r.Header + + // ------------- Optional header parameter "X-Primitive" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive")]; found { + var XPrimitive int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive", valueList[0], &XPrimitive, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive", Err: err}) + return + } + + params.XPrimitive = &XPrimitive + + } + + // ------------- Optional header parameter "X-Primitive-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Primitive-Exploded")]; found { + var XPrimitiveExploded int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Primitive-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Primitive-Exploded", valueList[0], &XPrimitiveExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Primitive-Exploded", Err: err}) + return + } + + params.XPrimitiveExploded = &XPrimitiveExploded + + } + + // ------------- Optional header parameter "X-Array-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array-Exploded")]; found { + var XArrayExploded []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array-Exploded", valueList[0], &XArrayExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array-Exploded", Err: err}) + return + } + + params.XArrayExploded = &XArrayExploded + + } + + // ------------- Optional header parameter "X-Array" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Array")]; found { + var XArray []int32 + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Array", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Array", valueList[0], &XArray, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Array", Err: err}) + return + } + + params.XArray = &XArray + + } + + // ------------- Optional header parameter "X-Object-Exploded" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object-Exploded")]; found { + var XObjectExploded Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object-Exploded", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object-Exploded", valueList[0], &XObjectExploded, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object-Exploded", Err: err}) + return + } + + params.XObjectExploded = &XObjectExploded + + } + + // ------------- Optional header parameter "X-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Object")]; found { + var XObject Object + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Object", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "X-Object", valueList[0], &XObject, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Object", Err: err}) + return + } + + params.XObject = &XObject + + } + + // ------------- Optional header parameter "X-Complex-Object" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Complex-Object")]; found { + var XComplexObject ComplexObject + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Complex-Object", Count: n}) + return + } + + err = json.Unmarshal([]byte(valueList[0]), &XComplexObject) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "X-Complex-Object", Err: err}) + return + } + + params.XComplexObject = &XComplexObject + + } + + // ------------- Optional header parameter "1-Starting-With-Number" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { + var N1StartingWithNumber string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "1-Starting-With-Number", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "1-Starting-With-Number", valueList[0], &N1StartingWithNumber, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1-Starting-With-Number", Err: err}) + return + } + + params.N1StartingWithNumber = &N1StartingWithNumber + + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetHeader(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetLabelPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetLabelPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("label", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetLabelPrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixExplodePrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id []int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeArray(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id Object + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixNoExplodeObject(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetMatrixPrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "id" ------------- + var id int32 + + err = runtime.BindStyledParameterWithOptions("matrix", "id", r.PathValue("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetMatrixPrimitive(w, r, id) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetPassThrough operation middleware +func (siw *ServerInterfaceWrapper) GetPassThrough(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param string + + param = r.PathValue("param") + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetPassThrough(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetDeepObject operation middleware +func (siw *ServerInterfaceWrapper) GetDeepObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetDeepObjectParams + + // ------------- Required query parameter "deepObj" ------------- + + err = runtime.BindQueryParameterWithOptions("deepObject", true, true, "deepObj", r.URL.Query(), ¶ms.DeepObj, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "deepObj"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "deepObj", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDeepObject(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryDelimited operation middleware +func (siw *ServerInterfaceWrapper) GetQueryDelimited(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryDelimitedParams + + // ------------- Optional query parameter "sa" ------------- + + err = runtime.BindQueryParameterWithOptions("spaceDelimited", false, false, "sa", r.URL.Query(), ¶ms.Sa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "sa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "sa", Err: err}) + } + return + } + + // ------------- Optional query parameter "pa" ------------- + + err = runtime.BindQueryParameterWithOptions("pipeDelimited", false, false, "pa", r.URL.Query(), ¶ms.Pa, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "pa"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "pa", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryDelimited(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetQueryForm operation middleware +func (siw *ServerInterfaceWrapper) GetQueryForm(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context + var params GetQueryFormParams + + // ------------- Optional query parameter "ea" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ea", r.URL.Query(), ¶ms.Ea, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ea"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ea", Err: err}) + } + return + } + + // ------------- Optional query parameter "a" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "a", r.URL.Query(), ¶ms.A, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "a"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "a", Err: err}) + } + return + } + + // ------------- Optional query parameter "eo" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "eo", r.URL.Query(), ¶ms.Eo, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "eo"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "eo", Err: err}) + } + return + } + + // ------------- Optional query parameter "o" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "o", r.URL.Query(), ¶ms.O, runtime.BindQueryParameterOptions{Type: "", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "o"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "o", Err: err}) + } + return + } + + // ------------- Optional query parameter "ep" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ep", r.URL.Query(), ¶ms.Ep, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ep"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ep", Err: err}) + } + return + } + + // ------------- Optional query parameter "p" ------------- + + err = runtime.BindQueryParameterWithOptions("form", false, false, "p", r.URL.Query(), ¶ms.P, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "p"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "p", Err: err}) + } + return + } + + // ------------- Optional query parameter "ps" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "ps", r.URL.Query(), ¶ms.Ps, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "ps"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "ps", Err: err}) + } + return + } + + // ------------- Optional query parameter "co" ------------- + + if paramValue := r.URL.Query().Get("co"); paramValue != "" { + + var value ComplexObject + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "co", Err: err}) + return + } + + params.Co = &value + + } + + // ------------- Optional query parameter "1s" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "1s", r.URL.Query(), ¶ms.N1s, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "1s"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "1s", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetQueryForm(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleExplodePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: true, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleExplodePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeArray operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param []int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "array", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeArray(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimpleNoExplodeObject operation middleware +func (siw *ServerInterfaceWrapper) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param Object + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimpleNoExplodeObject(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetSimplePrimitive operation middleware +func (siw *ServerInterfaceWrapper) GetSimplePrimitive(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "param" ------------- + var param int32 + + err = runtime.BindStyledParameterWithOptions("simple", "param", r.PathValue("param"), ¶m, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int32"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "param", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetSimplePrimitive(w, r, param) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetStartingWithNumber operation middleware +func (siw *ServerInterfaceWrapper) GetStartingWithNumber(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "1param" ------------- + var n1param string + + n1param = r.PathValue("1param") + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetStartingWithNumber(w, r, n1param) + })) + + 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.MethodGet+" "+options.BaseURL+"/contentObject/{param}", wrapper.GetContentObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/cookie", wrapper.GetCookie) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/enums", wrapper.EnumParams) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/header", wrapper.GetHeader) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelExplodeArray/{param}", wrapper.GetLabelExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelExplodeObject/{param}", wrapper.GetLabelExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelExplodePrimitive/{param}", wrapper.GetLabelExplodePrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelNoExplodeArray/{param}", wrapper.GetLabelNoExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelNoExplodeObject/{param}", wrapper.GetLabelNoExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/labelPrimitive/{param}", wrapper.GetLabelPrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixExplodeArray/{id}", wrapper.GetMatrixExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixExplodeObject/{id}", wrapper.GetMatrixExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixExplodePrimitive/{id}", wrapper.GetMatrixExplodePrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixNoExplodeArray/{id}", wrapper.GetMatrixNoExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixNoExplodeObject/{id}", wrapper.GetMatrixNoExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/matrixPrimitive/{id}", wrapper.GetMatrixPrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/passThrough/{param}", wrapper.GetPassThrough) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/queryForm", wrapper.GetQueryForm) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleExplodeArray/{param}", wrapper.GetSimpleExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleExplodeObject/{param}", wrapper.GetSimpleExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleExplodePrimitive/{param}", wrapper.GetSimpleExplodePrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleNoExplodeArray/{param}", wrapper.GetSimpleNoExplodeArray) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleNoExplodeObject/{param}", wrapper.GetSimpleNoExplodeObject) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simplePrimitive/{param}", wrapper.GetSimplePrimitive) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/startingWithNumber/{1param}", wrapper.GetStartingWithNumber) + + return m +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", + "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", + "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", + "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", + "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", + "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", + "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", + "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", + "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", + "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", + "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", + "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", + "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", + "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", + "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", + "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", + "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", + "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", + "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", + "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", + "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", + "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/internal/test/parameters/stdhttp/gen/types.gen.go b/internal/test/parameters/stdhttp/gen/types.gen.go new file mode 100644 index 0000000000..132c9c3499 --- /dev/null +++ b/internal/test/parameters/stdhttp/gen/types.gen.go @@ -0,0 +1,143 @@ +// Package stdhttpparamsgen 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 stdhttpparamsgen + +// Defines values for EnumParamsParamsEnumPathParam. +const ( + N100 EnumParamsParamsEnumPathParam = 100 + N200 EnumParamsParamsEnumPathParam = 200 +) + +// Valid indicates whether the value is a known member of the EnumParamsParamsEnumPathParam enum. +func (e EnumParamsParamsEnumPathParam) Valid() bool { + switch e { + case N100: + return true + case N200: + return true + default: + return false + } +} + +// ComplexObject defines model for ComplexObject. +type ComplexObject struct { + Id int `json:"Id"` + IsAdmin bool `json:"IsAdmin"` + Object Object `json:"Object"` +} + +// Object defines model for Object. +type Object struct { + FirstName string `json:"firstName"` + Role string `json:"role"` +} + +// GetCookieParams defines parameters for GetCookie. +type GetCookieParams struct { + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ep primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} + +// EnumParamsParams defines parameters for EnumParams. +type EnumParamsParams struct { + // EnumPathParam Parameter with enum values + EnumPathParam *EnumParamsParamsEnumPathParam `form:"enumPathParam,omitempty" json:"enumPathParam,omitempty"` +} + +// EnumParamsParamsEnumPathParam defines parameters for EnumParams. +type EnumParamsParamsEnumPathParam int32 + +// GetHeaderParams defines parameters for GetHeader. +type GetHeaderParams struct { + // XPrimitive primitive + XPrimitive *int32 `json:"X-Primitive,omitempty"` + + // XPrimitiveExploded primitive + XPrimitiveExploded *int32 `json:"X-Primitive-Exploded,omitempty"` + + // XArrayExploded exploded array + XArrayExploded *[]int32 `json:"X-Array-Exploded,omitempty"` + + // XArray array + XArray *[]int32 `json:"X-Array,omitempty"` + + // XObjectExploded exploded object + XObjectExploded *Object `json:"X-Object-Exploded,omitempty"` + + // XObject object + XObject *Object `json:"X-Object,omitempty"` + + // XComplexObject complex object + XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + + // N1StartingWithNumber name starting with number + N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` +} + +// GetDeepObjectParams defines parameters for GetDeepObject. +type GetDeepObjectParams struct { + // DeepObj deep object + DeepObj ComplexObject `json:"deepObj"` +} + +// GetQueryDelimitedParams defines parameters for GetQueryDelimited. +type GetQueryDelimitedParams struct { + // Sa space delimited array + Sa *[]int32 `json:"sa,omitempty"` + + // Pa pipe delimited array + Pa *[]int32 `json:"pa,omitempty"` +} + +// GetQueryFormParams defines parameters for GetQueryForm. +type GetQueryFormParams struct { + // Ea exploded array + Ea *[]int32 `form:"ea,omitempty" json:"ea,omitempty"` + + // A array + A *[]int32 `form:"a,omitempty" json:"a,omitempty"` + + // Eo exploded object + Eo *Object `form:"eo,omitempty" json:"eo,omitempty"` + + // O object + O *Object `form:"o,omitempty" json:"o,omitempty"` + + // Ep exploded primitive + Ep *int32 `form:"ep,omitempty" json:"ep,omitempty"` + + // P primitive + P *int32 `form:"p,omitempty" json:"p,omitempty"` + + // Ps primitive string + Ps *string `form:"ps,omitempty" json:"ps,omitempty"` + + // Co complex object + Co *ComplexObject `form:"co,omitempty" json:"co,omitempty"` + + // N1s name starting with number + N1s *string `form:"1s,omitempty" json:"1s,omitempty"` +} diff --git a/internal/test/parameters/stdhttp/server.cfg.yaml b/internal/test/parameters/stdhttp/server.cfg.yaml new file mode 100644 index 0000000000..cae77efded --- /dev/null +++ b/internal/test/parameters/stdhttp/server.cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: stdhttpparamsgen +generate: + std-http-server: true + embedded-spec: true +output: gen/server.gen.go diff --git a/internal/test/parameters/stdhttp/server.go b/internal/test/parameters/stdhttp/server.go new file mode 100644 index 0000000000..2b1d3b7261 --- /dev/null +++ b/internal/test/parameters/stdhttp/server.go @@ -0,0 +1,48 @@ +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=server.cfg.yaml ../parameters.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=types.cfg.yaml ../parameters.yaml + +package stdhttpparams + +import ( + "encoding/json" + "net/http" + + gen "github.com/oapi-codegen/oapi-codegen/v2/internal/test/parameters/stdhttp/gen" +) + +type Server struct{} + +var _ gen.ServerInterface = (*Server)(nil) + +func writeJSON(w http.ResponseWriter, v interface{}) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(v) +} + +func (s *Server) GetContentObject(w http.ResponseWriter, r *http.Request, param gen.ComplexObject) { writeJSON(w, param) } +func (s *Server) GetCookie(w http.ResponseWriter, r *http.Request, params gen.GetCookieParams) { writeJSON(w, params) } +func (s *Server) EnumParams(w http.ResponseWriter, r *http.Request, params gen.EnumParamsParams) { w.WriteHeader(http.StatusNoContent) } +func (s *Server) GetHeader(w http.ResponseWriter, r *http.Request, params gen.GetHeaderParams) { writeJSON(w, params) } +func (s *Server) GetLabelExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetLabelNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetLabelPrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetMatrixExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixExplodePrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeArray(w http.ResponseWriter, r *http.Request, id []int32) { writeJSON(w, id) } +func (s *Server) GetMatrixNoExplodeObject(w http.ResponseWriter, r *http.Request, id gen.Object) { writeJSON(w, id) } +func (s *Server) GetMatrixPrimitive(w http.ResponseWriter, r *http.Request, id int32) { writeJSON(w, id) } +func (s *Server) GetPassThrough(w http.ResponseWriter, r *http.Request, param string) { writeJSON(w, param) } +func (s *Server) GetDeepObject(w http.ResponseWriter, r *http.Request, params gen.GetDeepObjectParams) { writeJSON(w, params) } +func (s *Server) GetQueryDelimited(w http.ResponseWriter, r *http.Request, params gen.GetQueryDelimitedParams) { writeJSON(w, params) } +func (s *Server) GetQueryForm(w http.ResponseWriter, r *http.Request, params gen.GetQueryFormParams) { writeJSON(w, params) } +func (s *Server) GetSimpleExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimpleExplodePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeArray(w http.ResponseWriter, r *http.Request, param []int32) { writeJSON(w, param) } +func (s *Server) GetSimpleNoExplodeObject(w http.ResponseWriter, r *http.Request, param gen.Object) { writeJSON(w, param) } +func (s *Server) GetSimplePrimitive(w http.ResponseWriter, r *http.Request, param int32) { writeJSON(w, param) } +func (s *Server) GetStartingWithNumber(w http.ResponseWriter, r *http.Request, n1param string) { writeJSON(w, n1param) } diff --git a/internal/test/parameters/stdhttp/types.cfg.yaml b/internal/test/parameters/stdhttp/types.cfg.yaml new file mode 100644 index 0000000000..28ce3eff98 --- /dev/null +++ b/internal/test/parameters/stdhttp/types.cfg.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: stdhttpparamsgen +generate: + models: true +output: gen/types.gen.go diff --git a/internal/test/server/server.gen.go b/internal/test/server/server.gen.go index 67e89ff318..df00ee714b 100644 --- a/internal/test/server/server.gen.go +++ b/internal/test/server/server.gen.go @@ -4,6 +4,7 @@ package server import ( + "errors" "fmt" "net/http" "time" @@ -280,6 +281,7 @@ func (siw *ServerInterfaceWrapper) GetSimple(w http.ResponseWriter, r *http.Requ func (siw *ServerInterfaceWrapper) GetWithArgs(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params GetWithArgsParams @@ -288,22 +290,25 @@ func (siw *ServerInterfaceWrapper) GetWithArgs(w http.ResponseWriter, r *http.Re err = runtime.BindQueryParameterWithOptions("form", true, false, "optional_argument", r.URL.Query(), ¶ms.OptionalArgument, runtime.BindQueryParameterOptions{Type: "integer", Format: "int64"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "optional_argument", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "optional_argument"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "optional_argument", Err: err}) + } return } // ------------- Required query parameter "required_argument" ------------- - if paramValue := r.URL.Query().Get("required_argument"); paramValue != "" { - - } else { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "required_argument"}) - return - } - err = runtime.BindQueryParameterWithOptions("form", true, true, "required_argument", r.URL.Query(), ¶ms.RequiredArgument, runtime.BindQueryParameterOptions{Type: "integer", Format: "int64"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "required_argument", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "required_argument"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "required_argument", Err: err}) + } return } @@ -343,6 +348,7 @@ func (siw *ServerInterfaceWrapper) GetWithArgs(w http.ResponseWriter, r *http.Re func (siw *ServerInterfaceWrapper) GetWithReferences(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "global_argument" ------------- var globalArgument int64 @@ -377,6 +383,7 @@ func (siw *ServerInterfaceWrapper) GetWithReferences(w http.ResponseWriter, r *h func (siw *ServerInterfaceWrapper) GetWithContentType(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "content_type" ------------- var contentType GetWithContentTypeParamsContentType @@ -416,6 +423,7 @@ func (siw *ServerInterfaceWrapper) GetReservedKeyword(w http.ResponseWriter, r * func (siw *ServerInterfaceWrapper) CreateResource(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "argument" ------------- var argument Argument @@ -441,6 +449,7 @@ func (siw *ServerInterfaceWrapper) CreateResource(w http.ResponseWriter, r *http func (siw *ServerInterfaceWrapper) CreateResource2(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "inline_argument" ------------- var inlineArgument int @@ -458,7 +467,12 @@ func (siw *ServerInterfaceWrapper) CreateResource2(w http.ResponseWriter, r *htt err = runtime.BindQueryParameterWithOptions("form", true, false, "inline_query_argument", r.URL.Query(), ¶ms.InlineQueryArgument, runtime.BindQueryParameterOptions{Type: "integer", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "inline_query_argument", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "inline_query_argument"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "inline_query_argument", Err: err}) + } return } @@ -477,6 +491,7 @@ func (siw *ServerInterfaceWrapper) CreateResource2(w http.ResponseWriter, r *htt func (siw *ServerInterfaceWrapper) UpdateResource3(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "fallthrough" ------------- var pFallthrough int diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index 3632359f84..16c02ce305 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -242,6 +242,7 @@ func (siw *ServerInterfaceWrapper) RequiredTextBody(w http.ResponseWriter, r *ht func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string @@ -337,6 +338,7 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(w http.ResponseWriter, r *h func (siw *ServerInterfaceWrapper) HeadersExample(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index c1b3bd431c..37615230b7 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -191,11 +191,12 @@ func (siw *ServerInterfaceWrapper) RequiredTextBody(c *fiber.Ctx) error { func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(c *fiber.Ctx) error { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string - err = runtime.BindStyledParameterWithOptions("simple", "type", c.Params("type"), &pType, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "type", c.Params("type"), &pType, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter type: %w", err).Error()) } @@ -309,6 +310,7 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(c *fiber.Ctx) error { func (siw *ServerInterfaceWrapper) HeadersExample(c *fiber.Ctx) error { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index d854ee3cc7..466b116438 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -162,11 +162,12 @@ func (siw *ServerInterfaceWrapper) RequiredTextBody(c *gin.Context) { func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(c *gin.Context) { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string - err = runtime.BindStyledParameterWithOptions("simple", "type", c.Param("type"), &pType, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "type", c.Param("type"), &pType, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter type: %w", err), http.StatusBadRequest) return @@ -251,6 +252,7 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(c *gin.Context) { func (siw *ServerInterfaceWrapper) HeadersExample(c *gin.Context) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 48846b2438..028b8073bc 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -168,11 +168,12 @@ func (siw *ServerInterfaceWrapper) RequiredTextBody(w http.ResponseWriter, r *ht func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string - err = runtime.BindStyledParameterWithOptions("simple", "type", mux.Vars(r)["type"], &pType, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "type", mux.Vars(r)["type"], &pType, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "type", Err: err}) return @@ -263,6 +264,7 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(w http.ResponseWriter, r *h func (siw *ServerInterfaceWrapper) HeadersExample(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 7d81a25fe5..7ae7eb409b 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -124,6 +124,7 @@ func (w *ServerInterfaceWrapper) RequiredTextBody(ctx iris.Context) { func (w *ServerInterfaceWrapper) ReservedGoKeywordParameters(ctx iris.Context) { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string @@ -178,6 +179,7 @@ func (w *ServerInterfaceWrapper) URLEncodedExample(ctx iris.Context) { func (w *ServerInterfaceWrapper) HeadersExample(ctx iris.Context) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 3a14704185..41acd1741f 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -10,7 +10,7 @@ require ( github.com/getkin/kin-openapi v0.135.0 github.com/oapi-codegen/oapi-codegen/v2 v2.0.0-00010101000000-000000000000 github.com/oapi-codegen/oapi-codegen/v2/internal/test v0.0.0-00010101000000-000000000000 - github.com/oapi-codegen/runtime v1.3.1 + github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 ) diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index dc75c1b597..5a7589c118 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -63,8 +63,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+5xB9g= -github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oapi-codegen/testutil v1.1.0 h1:EufqpNg43acR3qzr3ObhXmWg3Sl2kwtRnUN5GYY4d5g= github.com/oapi-codegen/testutil v1.1.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw= github.com/oasdiff/yaml v0.0.9 h1:zQOvd2UKoozsSsAknnWoDJlSK4lC0mpmjfDsfqNwX48= diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 21e96956c5..e58751b75f 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -169,6 +169,7 @@ func (siw *ServerInterfaceWrapper) RequiredTextBody(w http.ResponseWriter, r *ht func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "type" ------------- var pType string @@ -264,6 +265,7 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(w http.ResponseWriter, r *h func (siw *ServerInterfaceWrapper) HeadersExample(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params HeadersExampleParams diff --git a/pkg/codegen/templates/chi/chi-middleware.tmpl b/pkg/codegen/templates/chi/chi-middleware.tmpl index 347b1dd95d..08402e2aca 100644 --- a/pkg/codegen/templates/chi/chi-middleware.tmpl +++ b/pkg/codegen/templates/chi/chi-middleware.tmpl @@ -13,6 +13,7 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- @@ -54,7 +55,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} - {{ if (or (or .Required .IsPassThrough) .IsJson) }} + {{ if (or .IsPassThrough .IsJson) }} if paramValue := r.URL.Query().Get("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} @@ -79,7 +80,12 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{if .IsStyled}} err = runtime.BindQueryParameterWithOptions("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", r.URL.Query(), ¶ms.{{.GoName}}, runtime.BindQueryParameterOptions{Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "{{.ParamName}}"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + } return } {{end}} @@ -159,7 +165,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) return diff --git a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl index c061240df3..0477ddcd34 100644 --- a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl @@ -18,7 +18,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", ctx.Param("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", ctx.Param("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) } @@ -37,7 +37,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} {{if .IsStyled}} - err = runtime.BindQueryParameter("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", ctx.QueryParams(), ¶ms.{{.GoName}}) + err = runtime.BindQueryParameterWithOptions("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", ctx.QueryParams(), ¶ms.{{.GoName}}, runtime.BindQueryParameterOptions{Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) } @@ -79,7 +79,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", valueList[0], &{{.GoName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: {{.Explode}}, Required: {{.Required}}}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", valueList[0], &{{.GoName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) } @@ -111,7 +111,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { {{end}} {{if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter {{.ParamName}}: %s", err)) } diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index 002d144101..ce20c29a4d 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -14,22 +14,32 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- var {{$varName := .GoVariableName}}{{$varName}} {{.TypeDef}} {{if .IsPassThrough}} - {{$varName}} = c.Query("{{.ParamName}}") + {{$varName}}, err = url.PathUnescape(c.Params("{{.ParamName}}")) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping path parameter '{{.ParamName}}': %w", err).Error()) + } {{end}} {{if .IsJson}} - err = json.Unmarshal([]byte(c.Query("{{.ParamName}}")), &{{$varName}}) - if err != nil { - return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter '{{.ParamName}}' as JSON: %w", err).Error()) + { + paramValue, decErr := url.PathUnescape(c.Params("{{.ParamName}}")) + if decErr != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unescaping path parameter '{{.ParamName}}': %w", decErr).Error()) + } + err = json.Unmarshal([]byte(paramValue), &{{$varName}}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter '{{.ParamName}}' as JSON: %w", err).Error()) + } } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", c.Params("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", c.Params("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err).Error()) } @@ -57,7 +67,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} - {{ if (or (or .Required .IsPassThrough) .IsJson) }} + {{ if (or .IsPassThrough .IsJson) }} if paramValue := c.Query("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} @@ -127,9 +137,10 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{end}} {{range .CookieParams}} - var cookie string + { + cookie := c.Cookies("{{.ParamName}}") - if cookie = c.Cookies("{{.ParamName}}"); cookie != "" { + if cookie != "" { {{- if .IsPassThrough}} params.{{.GoName}} = {{if .HasOptionalPointer}}}&{{end}}cookie @@ -153,7 +164,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { {{- if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie, &value, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err).Error()) } @@ -167,6 +178,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } {{- end}} + } {{end}} {{end}} diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl index 872590fa7a..87f16a56f8 100644 --- a/pkg/codegen/templates/gin/gin-wrappers.tmpl +++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl @@ -14,23 +14,24 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- var {{$varName := .GoVariableName}}{{$varName}} {{.TypeDef}} {{if .IsPassThrough}} - {{$varName}} = c.Query("{{.ParamName}}") + {{$varName}} = c.Param("{{.ParamName}}") {{end}} {{if .IsJson}} - err = json.Unmarshal([]byte(c.Query("{{.ParamName}}")), &{{$varName}}) + err = json.Unmarshal([]byte(c.Param("{{.ParamName}}")), &{{$varName}}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Error unmarshaling parameter '{{.ParamName}}' as JSON"), http.StatusBadRequest) return } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", c.Param("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", c.Param("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err), http.StatusBadRequest) return @@ -51,7 +52,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} - {{ if (or (or .Required .IsPassThrough) .IsJson) }} + {{ if (or .IsPassThrough .IsJson) }} if paramValue := c.Query("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} @@ -155,7 +156,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { {{- if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie, &value, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err), http.StatusBadRequest) return diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl index 1624a7ed6a..c971395fb8 100644 --- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl @@ -13,6 +13,7 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- @@ -29,7 +30,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", mux.Vars(r)["{{.ParamName}}"], &{{$varName}}, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", mux.Vars(r)["{{.ParamName}}"], &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) return @@ -54,7 +55,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} - {{ if (or (or .Required .IsPassThrough) .IsJson) }} + {{ if (or .IsPassThrough .IsJson) }} if paramValue := r.URL.Query().Get("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} @@ -79,7 +80,12 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{if .IsStyled}} err = runtime.BindQueryParameterWithOptions("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", r.URL.Query(), ¶ms.{{.GoName}}, runtime.BindQueryParameterOptions{Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "{{.ParamName}}"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + } return } {{end}} @@ -159,7 +165,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) return diff --git a/pkg/codegen/templates/iris/iris-middleware.tmpl b/pkg/codegen/templates/iris/iris-middleware.tmpl index 2a6cfaa769..769f2331bc 100644 --- a/pkg/codegen/templates/iris/iris-middleware.tmpl +++ b/pkg/codegen/templates/iris/iris-middleware.tmpl @@ -9,15 +9,16 @@ type MiddlewareFunc iris.Handler func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- var {{$varName := .GoVariableName}}{{$varName}} {{.TypeDef}} {{if .IsPassThrough}} - {{$varName}} = ctx.URLParam("{{.ParamName}}") + {{$varName}} = ctx.Params().Get("{{.ParamName}}") {{end}} {{if .IsJson}} - err = json.Unmarshal([]byte(ctx.URLParam("{{.ParamName}}")), &{{$varName}}) + err = json.Unmarshal([]byte(ctx.Params().Get("{{.ParamName}}")), &{{$varName}}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.WriteString("Error unmarshaling parameter '{{.ParamName}}' as JSON") @@ -53,7 +54,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { return } {{else}} - if paramValue := ctx.QueryParam("{{.ParamName}}"); paramValue != "" { + if paramValue := ctx.URLParam("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}paramValue {{end}} @@ -115,14 +116,14 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { {{end}} {{range .CookieParams}} - if cookie, err := ctx.Cookie("{{.ParamName}}"); err == nil { + if cookie := ctx.GetCookie("{{.ParamName}}"); cookie != "" { {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}cookie.Value + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}cookie {{end}} {{if .IsJson}} var value {{.TypeDef}} var decoded string - decoded, err := url.QueryUnescape(cookie.Value) + decoded, err := url.QueryUnescape(cookie) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.WriteString("Error unescaping cookie parameter '{{.ParamName}}'") @@ -138,7 +139,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { {{end}} {{if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.Writef("Invalid format for parameter {{.ParamName}}: %s", err) diff --git a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl index daadd981a7..00b0208555 100644 --- a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl @@ -13,6 +13,7 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Request) { {{if or .RequiresParamObject (gt (len .PathParams) 0) }} var err error + _ = err {{end}} {{range .PathParams}}// ------------- Path parameter "{{.ParamName}}" ------------- @@ -54,7 +55,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if (or (or .Required .IsPassThrough) (or .IsJson .IsStyled)) -}} // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- {{ end }} - {{ if (or (or .Required .IsPassThrough) .IsJson) }} + {{ if (or .IsPassThrough .IsJson) }} if paramValue := r.URL.Query().Get("{{.ParamName}}"); paramValue != "" { {{if .IsPassThrough}} @@ -79,7 +80,12 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{if .IsStyled}} err = runtime.BindQueryParameterWithOptions("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", r.URL.Query(), ¶ms.{{.GoName}}, runtime.BindQueryParameterOptions{Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "{{.ParamName}}"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) + } return } {{end}} @@ -159,7 +165,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ {{- if .IsStyled}} var value {{.TypeDef}} - err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("simple", "{{.ParamName}}", cookie.Value, &value, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationCookie, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) return From a2219c99dce3dacd590ae14a47495722f22a9dd4 Mon Sep 17 00:00:00 2001 From: Per Buer Date: Tue, 21 Apr 2026 20:50:39 +0200 Subject: [PATCH 33/62] Fix a streaming bug + document streaming through example (#1765) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: in GenerateGoSchema(), if a type isn't resolved, the error is swallowed, making it hard to track down * first stab at a streaming example. * generate flushing code if content-type is text/event-stream. * cleanup streaming example. * go mod tidy * comment cleanup. * cleanup after changing the build dependency to 1.21. * try to match the tmpl style of the rest of the template. * changes in template introduced a blank line in the generated code. adding these to git so build doesn't fail. * add a basic README. * remove toolchain directive * add the tools package to help fix deps. * add a test for a streaming endpoint. the server side will stagger writes and the client side will verify that this is happening. buffering will make the tests fail. * update generated code in tests * add the streaming endpoint to all the strict servers * update mod * update mod * updated generate code due to upstream changes. * Undo changes to strict-server example Revert the PR's additions to internal/test/strict-server so the existing harness is left intact. The streaming template change and dedicated example under examples/streaming/ remain. Co-Authored-By: Claude Opus 4.7 (1M context) * Add a streaming client to example Make an end-to-end example, with a client that prints the stream from the server. Co-Authored-By: Claude Opus 4.7 (1M context) * Fix lint issues * Parameterize streaming media types The strict-server template previously hard-coded a single content-type check (text/event-stream) to decide when to generate a flush-per-chunk response path. Replace the string match with a configurable, regex-based mechanism so the decision is declared once and applies to any streaming media type. - Add OutputOptions.StreamingContentTypes (list of regex patterns) and a defaultStreamingContentTypes list of text/event-stream, application/jsonl, and application/x-ndjson. User-provided patterns are merged on top of the defaults. - Compile the merged list up-front: OutputOptions.Validate() rejects invalid regexes via the existing CLI validation gate, and Generate() stashes the compiled regexes in globalState for template access. - Expose ResponseContentDefinition.IsStreamingContentType(), mirroring the existing IsJSON/IsSupported helpers, so strict-interface.tmpl can use {{if .IsStreamingContentType}} instead of an inline string match. The generated streaming code itself is unchanged; only the gate moved. - Document the new option in configuration-schema.json. - Update the streaming example spec from text/event-stream to application/jsonl, which matches what the server actually emits (newline-delimited JSON). The impl.go response-type reference is renamed to track the regenerated type name. application/jsonl is in the default list, so the streaming path still activates. Co-Authored-By: Claude Opus 4.7 (1M context) * streaming support in fiber/iris Port the flush-per-chunk response path from the stdhttp strict template into the fiber and iris variants, gated on the same IsStreamingContentType helper that was just added. Non-streaming responses still use the existing io.Copy call unchanged. - Iris uses the same http.Flusher type-assertion pattern as stdhttp, since iris.ResponseWriter implementations satisfy the interface. Falls back to io.Copy when the assertion fails. - Fiber uses fasthttp's SetBodyStreamWriter callback, which delivers a chunk to the client on each w.Flush() call — the body close moves inside the callback because fasthttp invokes it asynchronously. goimports adds the required bufio import when the streaming branch is actually emitted. The broader drift between the three strict-interface templates is tracked separately in oapi-codegen/oapi-codegen#2331 and is not touched here. Co-Authored-By: Claude Opus 4.7 (1M context) * fix slog key typo in streaming example The server example used "error:" as a slog key, which slog treats as a literal attribute name instead of the intended "error" key. Surfaced by Greptile review on PR #1765. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.7 (1M context) --- configuration-schema.json | 7 + examples/streaming/README.md | 17 + examples/streaming/client/main.go | 52 +++ examples/streaming/client/sse/cfg.yaml | 6 + examples/streaming/client/sse/generate.go | 3 + .../streaming/client/sse/streaming.gen.go | 222 +++++++++++ examples/streaming/sse.yaml | 28 ++ examples/streaming/stdhttp/Makefile | 36 ++ examples/streaming/stdhttp/main.go | 25 ++ examples/streaming/stdhttp/sse/cfg.yaml | 8 + examples/streaming/stdhttp/sse/generate.go | 3 + examples/streaming/stdhttp/sse/impl.go | 89 +++++ .../streaming/stdhttp/sse/streaming.gen.go | 371 ++++++++++++++++++ pkg/codegen/codegen.go | 14 +- pkg/codegen/configuration.go | 40 ++ pkg/codegen/operations.go | 13 + .../strict/strict-fiber-interface.tmpl | 37 +- .../templates/strict/strict-interface.tmpl | 32 +- .../strict/strict-iris-interface.tmpl | 32 +- 19 files changed, 1025 insertions(+), 10 deletions(-) create mode 100644 examples/streaming/README.md create mode 100644 examples/streaming/client/main.go create mode 100644 examples/streaming/client/sse/cfg.yaml create mode 100644 examples/streaming/client/sse/generate.go create mode 100644 examples/streaming/client/sse/streaming.gen.go create mode 100644 examples/streaming/sse.yaml create mode 100644 examples/streaming/stdhttp/Makefile create mode 100644 examples/streaming/stdhttp/main.go create mode 100644 examples/streaming/stdhttp/sse/cfg.yaml create mode 100644 examples/streaming/stdhttp/sse/generate.go create mode 100644 examples/streaming/stdhttp/sse/impl.go create mode 100644 examples/streaming/stdhttp/sse/streaming.gen.go diff --git a/configuration-schema.json b/configuration-schema.json index 21bfb0c0d5..cf5cb3b71c 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -192,6 +192,13 @@ "type": "string" } }, + "streaming-content-types": { + "type": "array", + "description": "Additional regex patterns matched against response Content-Type to decide when the strict server should generate a flush-per-chunk streaming response. Merged with the defaults (text/event-stream, application/jsonl, application/x-ndjson). Invalid regexes fail configuration validation.", + "items": { + "type": "string" + } + }, "nullable-type": { "type": "boolean", "description": "Whether to generate nullable type for nullable fields" diff --git a/examples/streaming/README.md b/examples/streaming/README.md new file mode 100644 index 0000000000..aeb445a82b --- /dev/null +++ b/examples/streaming/README.md @@ -0,0 +1,17 @@ +OpenAPI Code Generation Example - Streaming +------------------------------------------- + +This directory contains an example server using our code generator which implements +a simple streaming API with a single endpoint. + +This is the structure: +- `sse.yaml`: Contains the OpenAPI 3.0 specification +- `stdhttp/`: Contains the written and generated code for the server using the standard http package +- `client/`: Contains a client which reads the server stream and prints out the messages + +You can run both together to demonstrate the end-to-end behavior from +both client and server side. Run these commands in parallel: + + go run ./stdhttp + go run ./client + diff --git a/examples/streaming/client/main.go b/examples/streaming/client/main.go new file mode 100644 index 0000000000..78cf097a6c --- /dev/null +++ b/examples/streaming/client/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "log/slog" + "net/http" + "os" + "os/signal" + "syscall" + + "github.com/oapi-codegen/oapi-codegen/v2/examples/streaming/client/sse" +) + +func main() { + serverURL := flag.String("url", "http://localhost:8080", "server base URL") + flag.Parse() + + ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer cancel() + + client, err := sse.NewClient(*serverURL) + if err != nil { + slog.Error("NewClient failed", "error", err) + os.Exit(1) + } + + // Use the plain Client (not ClientWithResponses) so the response body stays + // an open io.Reader — ClientWithResponses would io.ReadAll the stream. + resp, err := client.GetStream(ctx) + if err != nil { + slog.Error("GetStream failed", "error", err) + os.Exit(1) + } + defer func() { _ = resp.Body.Close() }() + + if resp.StatusCode != http.StatusOK { + slog.Error("unexpected status", "status", resp.Status) + os.Exit(1) + } + + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + fmt.Println(scanner.Text()) + } + if err := scanner.Err(); err != nil && ctx.Err() == nil { + slog.Error("scan failed", "error", err) + os.Exit(1) + } +} diff --git a/examples/streaming/client/sse/cfg.yaml b/examples/streaming/client/sse/cfg.yaml new file mode 100644 index 0000000000..1e318e2d6e --- /dev/null +++ b/examples/streaming/client/sse/cfg.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: sse +output: streaming.gen.go +generate: + client: true + models: true diff --git a/examples/streaming/client/sse/generate.go b/examples/streaming/client/sse/generate.go new file mode 100644 index 0000000000..22de846215 --- /dev/null +++ b/examples/streaming/client/sse/generate.go @@ -0,0 +1,3 @@ +package sse + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml ../../sse.yaml diff --git a/examples/streaming/client/sse/streaming.gen.go b/examples/streaming/client/sse/streaming.gen.go new file mode 100644 index 0000000000..65a15573ff --- /dev/null +++ b/examples/streaming/client/sse/streaming.gen.go @@ -0,0 +1,222 @@ +// Package sse 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 sse + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "strings" +) + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetStream request + GetStream(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetStream(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetStreamRequest(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) +} + +// NewGetStreamRequest generates requests for GetStream +func NewGetStreamRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/") + 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 *Client) 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 *Client) 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 { + // GetStreamWithResponse request + GetStreamWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetStreamResponse, error) +} + +type GetStreamResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r GetStreamResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetStreamResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetStreamWithResponse request returning *GetStreamResponse +func (c *ClientWithResponses) GetStreamWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetStreamResponse, error) { + rsp, err := c.GetStream(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetStreamResponse(rsp) +} + +// ParseGetStreamResponse parses an HTTP response from a GetStreamWithResponse call +func ParseGetStreamResponse(rsp *http.Response) (*GetStreamResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetStreamResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/examples/streaming/sse.yaml b/examples/streaming/sse.yaml new file mode 100644 index 0000000000..ed972393d6 --- /dev/null +++ b/examples/streaming/sse.yaml @@ -0,0 +1,28 @@ +openapi: 3.0.0 +info: + title: Simple JSONL Streaming Service + version: 1.0.0 +paths: + /: + get: + summary: JSON Lines Stream + description: Provides a stream of JSON documents (one per line, application/jsonl) containing a timestamp and sequence number. + operationId: getStream + responses: + 200: + description: JSONL Stream + content: + application/jsonl: + schema: + type: object + properties: + time: + type: string + format: date-time + description: Timestamp of the event. + sequence: + type: integer + description: Sequence number of the event. + example: + time: "2023-11-20T10:30:00Z" + sequence: 1 \ No newline at end of file diff --git a/examples/streaming/stdhttp/Makefile b/examples/streaming/stdhttp/Makefile new file mode 100644 index 0000000000..66f60e4a23 --- /dev/null +++ b/examples/streaming/stdhttp/Makefile @@ -0,0 +1,36 @@ +SHELL:=/bin/bash + +YELLOW := \e[0;33m +RESET := \e[0;0m + +GOVER := $(shell go env GOVERSION) +GOMINOR := $(shell bash -c "cut -f2 -d. <<< $(GOVER)") + +define execute-if-go-122 +@{ \ +if [[ 22 -le $(GOMINOR) ]]; then \ + $1; \ +else \ + echo -e "$(YELLOW)Skipping task as you're running Go v1.$(GOMINOR).x which is < Go 1.22, which this module requires$(RESET)"; \ +fi \ +} +endef + +lint: + $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./...) + +lint-ci: + + $(call execute-if-go-122,$(GOBIN)/golangci-lint run ./... --out-format=colored-line-number --timeout=5m) + +generate: + $(call execute-if-go-122,go generate ./...) + +test: + $(call execute-if-go-122,go test -cover ./...) + +tidy: + $(call execute-if-go-122,go mod tidy) + +tidy-ci: + $(call execute-if-go-122,tidied -verbose) diff --git a/examples/streaming/stdhttp/main.go b/examples/streaming/stdhttp/main.go new file mode 100644 index 0000000000..385097fda3 --- /dev/null +++ b/examples/streaming/stdhttp/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "context" + "flag" + "github.com/oapi-codegen/oapi-codegen/v2/examples/streaming/stdhttp/sse" + "log/slog" + "os" + "os/signal" + "syscall" +) + +func main() { + port := flag.String("port", "8080", "port to serve on") + flag.Parse() + + server := sse.NewServer(*port) + ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer cancel() + err := server.Run(ctx) + if err != nil { + slog.Error("server run failed", "error", err) + os.Exit(1) + } +} diff --git a/examples/streaming/stdhttp/sse/cfg.yaml b/examples/streaming/stdhttp/sse/cfg.yaml new file mode 100644 index 0000000000..14ddeb0c2c --- /dev/null +++ b/examples/streaming/stdhttp/sse/cfg.yaml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: sse +output: streaming.gen.go +generate: + std-http-server: true + strict-server: true + models: true + embedded-spec: true diff --git a/examples/streaming/stdhttp/sse/generate.go b/examples/streaming/stdhttp/sse/generate.go new file mode 100644 index 0000000000..22de846215 --- /dev/null +++ b/examples/streaming/stdhttp/sse/generate.go @@ -0,0 +1,3 @@ +package sse + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml ../../sse.yaml diff --git a/examples/streaming/stdhttp/sse/impl.go b/examples/streaming/stdhttp/sse/impl.go new file mode 100644 index 0000000000..4dfdaed6d6 --- /dev/null +++ b/examples/streaming/stdhttp/sse/impl.go @@ -0,0 +1,89 @@ +package sse + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "time" +) + +type Server struct { + httpServer *http.Server +} + +func NewServer(port string) *Server { + s := &Server{} + strictHandler := NewStrictHandler(s, nil) + handler := Handler(strictHandler) + s.httpServer = &http.Server{ + Handler: handler, + Addr: ":" + port, + } + return s +} +func (s Server) Run(ctx context.Context) error { + go func() { + <-ctx.Done() + slog.Warn("context cancelled, shutting down") + ctxTimeout, cancel := context.WithTimeout(context.Background(), 5*time.Second) + err := s.httpServer.Shutdown(ctxTimeout) + cancel() + if err != nil { + slog.Error("httpServer.Shutdown() error", "error", err) + } + }() + + err := s.httpServer.ListenAndServe() + if err != nil && !errors.Is(err, http.ErrServerClosed) { + return fmt.Errorf("httpServer.ListenAndServe() error: %w", err) + } + return nil +} + +type SObject struct { + Time time.Time `json:"time"` + Sequence int `json:"sequence"` +} + +// GetStream handles GET / and will stream a JSON object every second. +func (Server) GetStream(ctx context.Context, _ GetStreamRequestObject) (GetStreamResponseObject, error) { + r, w := io.Pipe() // creates a pipe so that we can write to the response body asynchronously + go func() { + defer func() { _ = w.Close() }() + seq := 1 + ticker := time.NewTicker(time.Second) + for { + select { + case <-ctx.Done(): + slog.Info("request context done, closing stream") + return + case <-ticker.C: + content := getContent(seq) + if _, err := w.Write(content); err != nil { + return + } + if _, err := w.Write([]byte("\n")); err != nil { + return + } + seq++ + } + } + }() + return GetStream200ApplicationjsonlResponse{ + Body: r, + ContentLength: 0, + }, nil +} + +func getContent(seq int) []byte { + streamObject := SObject{ + Time: time.Now(), + Sequence: seq, + } + bytes, _ := json.Marshal(streamObject) + return bytes +} diff --git a/examples/streaming/stdhttp/sse/streaming.gen.go b/examples/streaming/stdhttp/sse/streaming.gen.go new file mode 100644 index 0000000000..a619348ee0 --- /dev/null +++ b/examples/streaming/stdhttp/sse/streaming.gen.go @@ -0,0 +1,371 @@ +//go:build go1.22 + +// Package sse 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 sse + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + // JSON Lines Stream + // (GET /) + GetStream(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 + +// GetStream operation middleware +func (siw *ServerInterfaceWrapper) GetStream(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetStream(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.MethodGet+" "+options.BaseURL+"/{$}", wrapper.GetStream) + + return m +} + +type GetStreamRequestObject struct { +} + +type GetStreamResponseObject interface { + VisitGetStreamResponse(w http.ResponseWriter) error +} + +type GetStream200ApplicationjsonlResponse struct { + Body io.Reader + ContentLength int64 +} + +func (response GetStream200ApplicationjsonlResponse) VisitGetStreamResponse(w http.ResponseWriter) error { + + w.Header().Set("Content-Type", "application/jsonl") + if response.ContentLength != 0 { + w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) + } + w.WriteHeader(200) + + if closer, ok := response.Body.(io.ReadCloser); ok { + defer closer.Close() + } + flusher, ok := w.(http.Flusher) + if !ok { + // If w doesn't support flushing, fall back to io.Copy. + _, err := io.Copy(w, response.Body) + return err + } + // text/event-stream messages are typically small; use a + // modest buffer and flush after each chunk so clients see + // events immediately instead of waiting on OS buffering. + buf := make([]byte, 4096) + for { + n, err := response.Body.Read(buf) + if n > 0 { + if _, writeErr := w.Write(buf[:n]); writeErr != nil { + return writeErr + } + flusher.Flush() + } + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + // JSON Lines Stream + // (GET /) + GetStream(ctx context.Context, request GetStreamRequestObject) (GetStreamResponseObject, error) +} + +type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc +type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc + +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 +} + +// GetStream operation middleware +func (sh *strictHandler) GetStream(w http.ResponseWriter, r *http.Request) { + var request GetStreamRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetStream(ctx, request.(GetStreamRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetStream") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetStreamResponseObject); ok { + if err := validResponse.VisitGetStreamResponse(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)) + } +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/2SSQW/bMAyF/wrB0wY4qZzc9AeGDcU2wD3tptpMwsKiNIkJVhT+7wPlLV2yi2VQeO97", + "fNAbshwS+jdU1pnQ48AxzwRfhm9fH2HQQiGyHGGgcuGRsMMLlcpJ0GO/dVuHS4cpk4TM6HHfRh3moKdq", + "tg/2OZLaMVEdC2dd1d9LuvBEFQLUhoF0aFiY0niOJFrhQxKCTAVmFuog5DzzGMzg4aUmmT/CmEQDi0UM", + "oBypaogZgkxQ6eeZZCSQc3ymssUWtDT55wk9fiJdF8QOC9WcpFILvXPODvMmadH/I9uQfgXryn7/stD3", + "HVoM9Lhzu/2m7zc799Q7v3feuR/WVh1PFIOpcrFAyiv13eO+quF2EytKTwR0IVFbS1+zAVmUjlSMsUa4", + "93m69nPvcEglBkWPU1DaNPXVtmphOeKyXCfp+YVGxcVGt4R/n01T1HOMobz+uYJHFqrv98vyOwAA///z", + "FQ4NgQIAAA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 2d0ed9a0c1..4542635733 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -27,6 +27,7 @@ import ( "maps" "net/http" "os" + "regexp" "runtime/debug" "slices" "sort" @@ -62,6 +63,9 @@ var globalState struct { // resolvedClientWrapperNames maps operationID to the resolved Go type name // for client response wrapper types (e.g., "createChatCompletion" -> "CreateChatCompletionResponseWrapper"). resolvedClientWrapperNames map[string]string + // streamingContentTypeRegexes are the compiled regexes (defaults + user) + // used by ResponseContentDefinition.IsStreamingContentType. + streamingContentTypeRegexes []*regexp.Regexp } // goImport represents a go package to be imported in the generated code @@ -181,6 +185,14 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { globalState.initialismsMap = makeInitialismsMap(opts.OutputOptions.AdditionalInitialisms) + // Compile streaming-content-type patterns (defaults merged with user-supplied). + // Validate() already caught syntax errors, but surface any regression here too. + streamingRegexes, err := compileStreamingContentTypes(opts.OutputOptions.StreamingContentTypes) + if err != nil { + return "", err + } + globalState.streamingContentTypeRegexes = streamingRegexes + // Multi-pass name resolution: gather all schemas, then resolve names globally. // Only enabled when resolve-type-name-collisions is set. if opts.OutputOptions.ResolveTypeNameCollisions { @@ -208,7 +220,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { t := template.New("oapi-codegen").Funcs(TemplateFunctions) // This parses all of our own template files into the template object // above - err := LoadTemplates(templates, t) + err = LoadTemplates(templates, t) if err != nil { return "", fmt.Errorf("error parsing oapi-codegen templates: %w", err) } diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index abdab8f049..724444690a 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -4,8 +4,18 @@ import ( "errors" "fmt" "reflect" + "regexp" ) +// defaultStreamingContentTypes are the regex patterns matched against +// response Content-Type to decide when the strict-server should emit a +// flush-per-chunk streaming path. User-supplied patterns are merged on top. +var defaultStreamingContentTypes = []string{ + "text/event-stream", + "application/jsonl", + "application/x-ndjson", +} + type AdditionalImport struct { Alias string `yaml:"alias,omitempty"` Package string `yaml:"package"` @@ -329,6 +339,12 @@ type OutputOptions struct { // AdditionalInitialisms is a list of additional initialisms to use when generating names. // NOTE that this has no effect unless the `name-normalizer` is set to `ToCamelCaseWithInitialisms` AdditionalInitialisms []string `yaml:"additional-initialisms,omitempty"` + // StreamingContentTypes are regex patterns matched against response + // Content-Type to decide when to generate a flush-per-chunk streaming + // response path. User-provided patterns are merged with the defaults + // (text/event-stream, application/jsonl, application/x-ndjson); invalid + // regexes fail Validate(). + StreamingContentTypes []string `yaml:"streaming-content-types,omitempty"` // Whether to generate nullable type for nullable fields NullableType bool `yaml:"nullable-type,omitempty"` @@ -384,9 +400,33 @@ func (oo OutputOptions) Validate() map[string]string { } } + if _, err := compileStreamingContentTypes(oo.StreamingContentTypes); err != nil { + return map[string]string{ + "streaming-content-types": err.Error(), + } + } + return nil } +// compileStreamingContentTypes returns the merged default + user-provided +// patterns compiled into regexes. The first compile error is returned +// including the offending pattern. +func compileStreamingContentTypes(user []string) ([]*regexp.Regexp, error) { + all := make([]string, 0, len(defaultStreamingContentTypes)+len(user)) + all = append(all, defaultStreamingContentTypes...) + all = append(all, user...) + out := make([]*regexp.Regexp, 0, len(all)) + for _, p := range all { + re, err := regexp.Compile(p) + if err != nil { + return nil, fmt.Errorf("invalid streaming-content-type pattern %q: %w", p, err) + } + out = append(out, re) + } + return out, nil +} + type OutputOptionsOverlay struct { Path string `yaml:"path"` diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 69f8fd9765..8b1a01bd45 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -594,6 +594,19 @@ func (r ResponseContentDefinition) IsJSON() bool { return util.IsMediaTypeJson(r.ContentType) } +// IsStreamingContentType reports whether this response's media type matches +// any configured streaming-content-types pattern (defaults merged with +// OutputOptions.StreamingContentTypes). Templates use this to emit a +// flush-per-chunk streaming path instead of a buffered io.Copy. +func (r ResponseContentDefinition) IsStreamingContentType() bool { + for _, re := range globalState.streamingContentTypeRegexes { + if re.MatchString(r.ContentType) { + return true + } + } + return false +} + type ResponseHeaderDefinition struct { Name string GoName string diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index 11d1cbaad0..b4543b9b20 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -102,11 +102,38 @@ defer writer.Close() return {{if $hasBodyVar}}response.Body{{else}}response{{end}}(writer); {{else -}} - if closer, ok := response.Body.(io.ReadCloser); ok { - defer closer.Close() - } - _, err := io.Copy(ctx.Response().BodyWriter(), response.Body) - return err + {{if .IsStreamingContentType -}} + // Fiber/fasthttp streams through a callback: fasthttp emits + // a chunk each time we call w.Flush(), so clients see + // streaming data immediately instead of waiting on buffering. + ctx.Response().SetBodyStreamWriter(func(w *bufio.Writer) { + if closer, ok := response.Body.(io.ReadCloser); ok { + defer closer.Close() + } + buf := make([]byte, 4096) + for { + n, err := response.Body.Read(buf) + if n > 0 { + if _, writeErr := w.Write(buf[:n]); writeErr != nil { + return + } + if flushErr := w.Flush(); flushErr != nil { + return + } + } + if err != nil { + return + } + } + }) + return nil + {{else -}} + if closer, ok := response.Body.(io.ReadCloser); ok { + defer closer.Close() + } + _, err := io.Copy(ctx.Response().BodyWriter(), response.Body) + return err + {{end}}{{/* if .IsStreamingContentType */ -}} {{end}}{{/* if eq .NameTag "JSON" */ -}} } {{end}} diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index fc1f53ca01..5814ad1c3a 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -152,8 +152,36 @@ if closer, ok := response.Body.(io.ReadCloser); ok { defer closer.Close() } - _, err := io.Copy(w, response.Body) - return err + {{if .IsStreamingContentType -}} + flusher, ok := w.(http.Flusher) + if !ok { + // If w doesn't support flushing, fall back to io.Copy. + _, err := io.Copy(w, response.Body) + return err + } + // text/event-stream messages are typically small; use a + // modest buffer and flush after each chunk so clients see + // events immediately instead of waiting on OS buffering. + buf := make([]byte, 4096) + for { + n, err := response.Body.Read(buf) + if n > 0 { + if _, writeErr := w.Write(buf[:n]); writeErr != nil { + return writeErr + } + flusher.Flush() + } + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + {{else -}} + _, err := io.Copy(w, response.Body) + return err + {{end}}{{/* if .IsStreamingContentType */ -}} {{end}}{{/* if eq .NameTag "Text" */ -}} {{end}}{{/* if .IsJSON */ -}} } diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index aa7e166d9f..8fcf26da1d 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -107,8 +107,36 @@ if closer, ok := response.Body.(io.ReadCloser); ok { defer closer.Close() } - _, err := io.Copy(ctx.ResponseWriter(), response.Body) - return err + {{if .IsStreamingContentType -}} + flusher, ok := ctx.ResponseWriter().(http.Flusher) + if !ok { + // Fall back to buffered copy when the response writer + // doesn't support flushing. + _, err := io.Copy(ctx.ResponseWriter(), response.Body) + return err + } + // Flush after each chunk so streaming clients see data + // immediately instead of waiting on buffering. + buf := make([]byte, 4096) + for { + n, err := response.Body.Read(buf) + if n > 0 { + if _, writeErr := ctx.ResponseWriter().Write(buf[:n]); writeErr != nil { + return writeErr + } + flusher.Flush() + } + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + {{else -}} + _, err := io.Copy(ctx.ResponseWriter(), response.Body) + return err + {{end}}{{/* if .IsStreamingContentType */ -}} {{end}}{{/* if eq .NameTag "JSON" */ -}} } {{end}} From e3ff50c176206eebab58dc2eefd577edd7fc787a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 13:19:48 -0700 Subject: [PATCH 34/62] chore(deps): update release-drafter/release-drafter action to v7.2.0 (.github/workflows) (#2322) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 17a281c8cb..ec1c0685ae 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@139054aeaa9adc52ab36ddf67437541f039b88e2 # v7.1.1 + - uses: release-drafter/release-drafter@5de93583980a40bd78603b6dfdcda5b4df377b32 # v7.2.0 with: name: next tag: next From 6a24613faa869959e4cce2997dff912c1ff1583c Mon Sep 17 00:00:00 2001 From: actatum Date: Tue, 21 Apr 2026 17:11:00 -0400 Subject: [PATCH 35/62] Strictgin error handler (#1600) * adding strictgin-error-handler * gomod * gomod * fix gomod again * fix gomod again * sq * feat: replace single error handler with three-callback pattern in strict gin template Split the single ErrorHandlerFunc into three distinct callbacks to give callers control over error responses by category: - RequestErrorHandlerFunc: request parsing/binding errors (default 400) - HandlerErrorFunc: application handler errors (default 500) - ResponseErrorHandlerFunc: response serialization errors (default 500) This also fixes two bugs in the original template: - Missing multipart boundary now passes http.ErrMissingBoundary instead of a nil error - Unexpected response type now passes a descriptive error instead of nil Co-Authored-By: Claude Opus 4.6 * Update pkg/codegen/templates/strict/strict-gin.tmpl Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Regenerate boilerplate I accepted a Greptile code fix, but this affected generated code. --------- Co-authored-by: Jamie Tanna Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.6 Co-authored-by: Marcin Romaszewicz Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- .../issues/issue-1093/api/child/child.gen.go | 54 ++++- .../issue-1093/api/parent/parent.gen.go | 54 ++++- .../issue-1208-1209/issue-multi-json.gen.go | 54 ++++- .../test/issues/issue-1212/pkg1/pkg1.gen.go | 54 ++++- .../test/issues/issue-1212/pkg2/pkg2.gen.go | 47 ++++- .../test/issues/issue-1298/issue1298.gen.go | 57 ++++- internal/test/strict-server/gin/server.gen.go | 197 ++++++++++-------- pkg/codegen/templates/strict/strict-gin.tmpl | 78 +++++-- 8 files changed, 463 insertions(+), 132 deletions(-) diff --git a/internal/test/issues/issue-1093/api/child/child.gen.go b/internal/test/issues/issue-1093/api/child/child.gen.go index d6a7ae9bfc..3716a0ba9c 100644 --- a/internal/test/issues/issue-1093/api/child/child.gen.go +++ b/internal/test/issues/issue-1093/api/child/child.gen.go @@ -111,13 +111,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // GetPets operation middleware @@ -134,14 +179,13 @@ func (sh *strictHandler) GetPets(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(GetPetsResponseObject); ok { if err := validResponse.VisitGetPetsResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/internal/test/issues/issue-1093/api/parent/parent.gen.go b/internal/test/issues/issue-1093/api/parent/parent.gen.go index 462818dea7..0aada7045e 100644 --- a/internal/test/issues/issue-1093/api/parent/parent.gen.go +++ b/internal/test/issues/issue-1093/api/parent/parent.gen.go @@ -116,13 +116,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // GetPets operation middleware @@ -139,14 +184,13 @@ func (sh *strictHandler) GetPets(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(GetPetsResponseObject); ok { if err := validResponse.VisitGetPetsResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index 50ec7337a5..4989ab412c 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -420,13 +420,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // Test operation middleware @@ -443,14 +488,13 @@ func (sh *strictHandler) Test(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(TestResponseObject); ok { if err := validResponse.VisitTestResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index 50244c424f..643b7e6866 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -320,13 +320,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // Test operation middleware @@ -343,14 +388,13 @@ func (sh *strictHandler) Test(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(TestResponseObject); ok { if err := validResponse.VisitTestResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go index 5a994ed06f..d4c338cce7 100644 --- a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go @@ -189,13 +189,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // Base64 encoded, gzipped, json marshaled Swagger object diff --git a/internal/test/issues/issue-1298/issue1298.gen.go b/internal/test/issues/issue-1298/issue1298.gen.go index a45d921e58..67bb5b92d5 100644 --- a/internal/test/issues/issue-1298/issue1298.gen.go +++ b/internal/test/issues/issue-1298/issue1298.gen.go @@ -358,13 +358,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // Test operation middleware @@ -374,8 +419,7 @@ func (sh *strictHandler) Test(ctx *gin.Context) { var body TestApplicationTestPlusJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -392,13 +436,12 @@ func (sh *strictHandler) Test(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(TestResponseObject); ok { if err := validResponse.VisitTestResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 466b116438..489adcae13 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -1065,13 +1065,58 @@ type StrictServerInterface interface { type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions{ + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } // JSONExample operation middleware @@ -1081,8 +1126,7 @@ func (sh *strictHandler) JSONExample(ctx *gin.Context) { var body JSONExampleJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -1099,14 +1143,13 @@ func (sh *strictHandler) JSONExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(JSONExampleResponseObject); ok { if err := validResponse.VisitJSONExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1114,11 +1157,11 @@ func (sh *strictHandler) JSONExample(ctx *gin.Context) { func (sh *strictHandler) MultipartExample(ctx *gin.Context) { var request MultipartExampleRequestObject - if reader, err := ctx.Request.MultipartReader(); err == nil { - request.Body = reader - } else { - ctx.Error(err) + if reader, err := ctx.Request.MultipartReader(); err != nil { + sh.options.RequestErrorHandlerFunc(ctx, err) return + } else { + request.Body = reader } handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { @@ -1131,14 +1174,13 @@ func (sh *strictHandler) MultipartExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(MultipartExampleResponseObject); ok { if err := validResponse.VisitMultipartExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1147,10 +1189,10 @@ func (sh *strictHandler) MultipartRelatedExample(ctx *gin.Context) { var request MultipartRelatedExampleRequestObject if _, params, err := mime.ParseMediaType(ctx.Request.Header.Get("Content-Type")); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } else if boundary := params["boundary"]; boundary == "" { - ctx.Error(http.ErrMissingBoundary) + sh.options.RequestErrorHandlerFunc(ctx, http.ErrMissingBoundary) return } else { request.Body = multipart.NewReader(ctx.Request.Body, boundary) @@ -1166,14 +1208,13 @@ func (sh *strictHandler) MultipartRelatedExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(MultipartRelatedExampleResponseObject); ok { if err := validResponse.VisitMultipartRelatedExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1186,8 +1227,7 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) { var body MultipleRequestAndResponseTypesJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -1196,12 +1236,12 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) { } if strings.HasPrefix(ctx.GetHeader("Content-Type"), "application/x-www-form-urlencoded") { if err := ctx.Request.ParseForm(); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } var body MultipleRequestAndResponseTypesFormdataRequestBody if err := runtime.BindForm(&body, ctx.Request.Form, nil, nil); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } request.FormdataBody = &body @@ -1210,17 +1250,17 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) { request.Body = ctx.Request.Body } if strings.HasPrefix(ctx.GetHeader("Content-Type"), "multipart/form-data") { - if reader, err := ctx.Request.MultipartReader(); err == nil { - request.MultipartBody = reader - } else { - ctx.Error(err) + if reader, err := ctx.Request.MultipartReader(); err != nil { + sh.options.RequestErrorHandlerFunc(ctx, err) return + } else { + request.MultipartBody = reader } } if strings.HasPrefix(ctx.GetHeader("Content-Type"), "text/plain") { data, err := io.ReadAll(ctx.Request.Body) if err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } if len(data) > 0 { @@ -1239,14 +1279,13 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(MultipleRequestAndResponseTypesResponseObject); ok { if err := validResponse.VisitMultipleRequestAndResponseTypesResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1256,8 +1295,7 @@ func (sh *strictHandler) RequiredJSONBody(ctx *gin.Context) { var body RequiredJSONBodyJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } request.Body = &body @@ -1272,14 +1310,13 @@ func (sh *strictHandler) RequiredJSONBody(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(RequiredJSONBodyResponseObject); ok { if err := validResponse.VisitRequiredJSONBodyResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1289,7 +1326,7 @@ func (sh *strictHandler) RequiredTextBody(ctx *gin.Context) { data, err := io.ReadAll(ctx.Request.Body) if err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } body := RequiredTextBodyTextRequestBody(data) @@ -1305,14 +1342,13 @@ func (sh *strictHandler) RequiredTextBody(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(RequiredTextBodyResponseObject); ok { if err := validResponse.VisitRequiredTextBodyResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1332,14 +1368,13 @@ func (sh *strictHandler) ReservedGoKeywordParameters(ctx *gin.Context, pType str response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok { if err := validResponse.VisitReservedGoKeywordParametersResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1350,8 +1385,7 @@ func (sh *strictHandler) ReusableResponses(ctx *gin.Context) { var body ReusableResponsesJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -1368,14 +1402,13 @@ func (sh *strictHandler) ReusableResponses(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(ReusableResponsesResponseObject); ok { if err := validResponse.VisitReusableResponsesResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1385,7 +1418,7 @@ func (sh *strictHandler) TextExample(ctx *gin.Context) { data, err := io.ReadAll(ctx.Request.Body) if err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } if len(data) > 0 { @@ -1403,14 +1436,13 @@ func (sh *strictHandler) TextExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(TextExampleResponseObject); ok { if err := validResponse.VisitTextExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1430,14 +1462,13 @@ func (sh *strictHandler) UnknownExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(UnknownExampleResponseObject); ok { if err := validResponse.VisitUnknownExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1459,14 +1490,13 @@ func (sh *strictHandler) UnspecifiedContentType(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(UnspecifiedContentTypeResponseObject); ok { if err := validResponse.VisitUnspecifiedContentTypeResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1475,12 +1505,12 @@ func (sh *strictHandler) URLEncodedExample(ctx *gin.Context) { var request URLEncodedExampleRequestObject if err := ctx.Request.ParseForm(); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } var body URLEncodedExampleFormdataRequestBody if err := runtime.BindForm(&body, ctx.Request.Form, nil, nil); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } request.Body = &body @@ -1495,14 +1525,13 @@ func (sh *strictHandler) URLEncodedExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(URLEncodedExampleResponseObject); ok { if err := validResponse.VisitURLEncodedExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1515,8 +1544,7 @@ func (sh *strictHandler) HeadersExample(ctx *gin.Context, params HeadersExampleP var body HeadersExampleJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -1533,14 +1561,13 @@ func (sh *strictHandler) HeadersExample(ctx *gin.Context, params HeadersExampleP response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(HeadersExampleResponseObject); ok { if err := validResponse.VisitHeadersExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } @@ -1551,8 +1578,7 @@ func (sh *strictHandler) UnionExample(ctx *gin.Context) { var body UnionExampleJSONRequestBody if err := ctx.ShouldBindJSON(&body); err != nil { if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } } else { @@ -1569,14 +1595,13 @@ func (sh *strictHandler) UnionExample(ctx *gin.Context) { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.(UnionExampleResponseObject); ok { if err := validResponse.VisitUnionExampleResponse(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } diff --git a/pkg/codegen/templates/strict/strict-gin.tmpl b/pkg/codegen/templates/strict/strict-gin.tmpl index 86040d6d76..893e4b4046 100644 --- a/pkg/codegen/templates/strict/strict-gin.tmpl +++ b/pkg/codegen/templates/strict/strict-gin.tmpl @@ -1,13 +1,58 @@ type StrictHandlerFunc = strictgin.StrictGinHandlerFunc type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictGinServerOptions struct { + // RequestErrorHandlerFunc is called when a request cannot be parsed or + // decoded. It is invoked for JSON bind failures, form parse/bind errors, + // multipart reader errors, media type parse errors, missing multipart + // boundaries, and request body read errors. The default returns 400. + RequestErrorHandlerFunc func(ctx *gin.Context, err error) + // HandlerErrorFunc is called when the application handler (or any + // middleware wrapping it) returns a non-nil error. The default returns 500. + HandlerErrorFunc func(ctx *gin.Context, err error) + // ResponseErrorHandlerFunc is called when the response object fails to + // serialize (Visit*Response returns an error) or when the handler returns + // an unexpected response type. The default returns 500. + ResponseErrorHandlerFunc func(ctx *gin.Context, err error) +} + func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { - return &strictHandler{ssi: ssi, middlewares: middlewares} + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictGinServerOptions { + RequestErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + }, + HandlerErrorFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + ResponseErrorHandlerFunc: func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictGinServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + } + } + if options.HandlerErrorFunc == nil { + options.HandlerErrorFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(ctx *gin.Context, err error) { + ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + } + } + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } type strictHandler struct { ssi StrictServerInterface middlewares []StrictMiddlewareFunc + options StrictGinServerOptions } {{range .}} @@ -37,13 +82,11 @@ type strictHandler struct { if err := ctx.ShouldBindJSON(&body); err != nil { {{if not .Required -}} if !errors.Is(err, io.EOF) { - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } {{else -}} - ctx.Status(http.StatusBadRequest) - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return {{end -}} } {{if not .Required -}} else { {{end}} @@ -51,29 +94,29 @@ type strictHandler struct { {{if not .Required -}} } {{end}} {{else if eq .NameTag "Formdata" -}} if err := ctx.Request.ParseForm(); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } var body {{$opid}}{{.NameTag}}RequestBody if err := runtime.BindForm(&body, ctx.Request.Form, nil, nil); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = &body {{else if eq .NameTag "Multipart" -}} {{if eq .ContentType "multipart/form-data" -}} - if reader, err := ctx.Request.MultipartReader(); err == nil { - request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = reader - } else { - ctx.Error(err) + if reader, err := ctx.Request.MultipartReader(); err != nil { + sh.options.RequestErrorHandlerFunc(ctx, err) return + } else { + request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = reader } {{else -}} if _, params, err := mime.ParseMediaType(ctx.Request.Header.Get("Content-Type")); err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } else if boundary := params["boundary"]; boundary == "" { - ctx.Error(http.ErrMissingBoundary) + sh.options.RequestErrorHandlerFunc(ctx, http.ErrMissingBoundary) return } else { request.{{if $multipleBodies}}{{.NameTag}}{{end}}Body = multipart.NewReader(ctx.Request.Body, boundary) @@ -82,7 +125,7 @@ type strictHandler struct { {{else if eq .NameTag "Text" -}} data, err := io.ReadAll(ctx.Request.Body) if err != nil { - ctx.Error(err) + sh.options.RequestErrorHandlerFunc(ctx, err) return } {{if not .Required -}} @@ -109,14 +152,13 @@ type strictHandler struct { response, err := handler(ctx, request) if err != nil { - ctx.Error(err) - ctx.Status(http.StatusInternalServerError) + sh.options.HandlerErrorFunc(ctx, err) } else if validResponse, ok := response.({{$opid | ucFirst}}ResponseObject); ok { if err := validResponse.Visit{{$opid}}Response(ctx.Writer); err != nil { - ctx.Error(err) + sh.options.ResponseErrorHandlerFunc(ctx, err) } } else if response != nil { - ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) } } {{end}} From 6a413495c919e7f0058bb6b5d6e5fab02388466b Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Wed, 22 Apr 2026 04:00:14 +0300 Subject: [PATCH 36/62] fix: include additional types for array response type (#1930) fix: emit additional types for inline array response schemas in strict-server When a response `content` schema was an inline `array` of `object` (e.g. with `additionalProperties: true`), the strict-server template declared `JSONResponse []JSONResponse_Item` but never emitted the `_Item` type itself, so generated code failed to build with `undefined: JSONResponse_Item`. Range over `.Schema.AdditionalTypes` in `strict-interface.tmpl` and emit each type declaration (using `=` for aliases), so inline helper types end up alongside the response type that references them. Adds a test case at `internal/test/issues/issue-1277/` covering models, client, chi-server, and strict-server generation for the repro spec. Fixes #1277 --- internal/test/issues/issue-1277/config.yaml | 8 + .../issues/issue-1277/content-array.gen.go | 489 ++++++++++++++++++ internal/test/issues/issue-1277/generate.go | 3 + internal/test/issues/issue-1277/spec.yaml | 23 + internal/test/strict-server/chi/server.gen.go | 2 + .../test/strict-server/echo/server.gen.go | 2 + internal/test/strict-server/gin/server.gen.go | 2 + .../test/strict-server/gorilla/server.gen.go | 2 + .../test/strict-server/stdhttp/server.gen.go | 2 + .../templates/strict/strict-interface.tmpl | 4 + 10 files changed, 537 insertions(+) create mode 100644 internal/test/issues/issue-1277/config.yaml create mode 100644 internal/test/issues/issue-1277/content-array.gen.go create mode 100644 internal/test/issues/issue-1277/generate.go create mode 100644 internal/test/issues/issue-1277/spec.yaml diff --git a/internal/test/issues/issue-1277/config.yaml b/internal/test/issues/issue-1277/config.yaml new file mode 100644 index 0000000000..f4c4a686a2 --- /dev/null +++ b/internal/test/issues/issue-1277/config.yaml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: issue1277 +generate: + models: true + client: true + chi-server: true + strict-server: true +output: content-array.gen.go diff --git a/internal/test/issues/issue-1277/content-array.gen.go b/internal/test/issues/issue-1277/content-array.gen.go new file mode 100644 index 0000000000..41eb70440a --- /dev/null +++ b/internal/test/issues/issue-1277/content-array.gen.go @@ -0,0 +1,489 @@ +// Package issue1277 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 issue1277 + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/go-chi/chi/v5" + strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" +) + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // Test request + Test(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) Test(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewTestRequest(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) +} + +// NewTestRequest generates requests for Test +func NewTestRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/test") + 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 *Client) 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 *Client) 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 { + // TestWithResponse request + TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) +} + +type TestResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *[]Test_200_Item +} +type Test_200_Item struct { + Field1 *string `json:"field1,omitempty"` + Field2 *string `json:"field2,omitempty"` + AdditionalProperties map[string]interface{} `json:"-"` +} + +// Status returns HTTPResponse.Status +func (r TestResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r TestResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// TestWithResponse request returning *TestResponse +func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { + rsp, err := c.Test(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseTestResponse(rsp) +} + +// ParseTestResponse parses an HTTP response from a TestWithResponse call +func ParseTestResponse(rsp *http.Response) (*TestResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &TestResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest []Test_200_Item + 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 { + + // (GET /test) + Test(w http.ResponseWriter, r *http.Request) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// (GET /test) +func (_ Unimplemented) Test(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// 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 + +// Test operation middleware +func (siw *ServerInterfaceWrapper) Test(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.Test(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, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + 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, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + 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, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/test", wrapper.Test) + }) + + return r +} + +type TestRequestObject struct { +} + +type TestResponseObject interface { + VisitTestResponse(w http.ResponseWriter) error +} + +type Test200JSONResponse []Test200JSONResponse_Item + +type Test200JSONResponse_Item struct { + Field1 *string `json:"field1,omitempty"` + Field2 *string `json:"field2,omitempty"` + AdditionalProperties map[string]interface{} `json:"-"` +} + +func (response Test200JSONResponse) VisitTestResponse(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 +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (GET /test) + Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) +} + +type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc +type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc + +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 +} + +// Test operation middleware +func (sh *strictHandler) Test(w http.ResponseWriter, r *http.Request) { + var request TestRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.Test(ctx, request.(TestRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "Test") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(TestResponseObject); ok { + if err := validResponse.VisitTestResponse(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/issues/issue-1277/generate.go b/internal/test/issues/issue-1277/generate.go new file mode 100644 index 0000000000..7158b4df22 --- /dev/null +++ b/internal/test/issues/issue-1277/generate.go @@ -0,0 +1,3 @@ +package issue1277 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue-1277/spec.yaml b/internal/test/issues/issue-1277/spec.yaml new file mode 100644 index 0000000000..bd03fd2b97 --- /dev/null +++ b/internal/test/issues/issue-1277/spec.yaml @@ -0,0 +1,23 @@ +openapi: "3.0.1" +info: + title: a + version: 1.0.0 +paths: + /test: + get: + operationId: test + responses: + "200": + description: desc + content: + application/json: + schema: + type: array + items: + type: object + properties: + field1: + type: string + field2: + type: string + additionalProperties: true diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index 16c02ce305..a86b27c501 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -1191,6 +1191,8 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } +type UnionExample200JSONResponse0 = string + func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 067448ae36..88036c38f4 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -911,6 +911,8 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } +type UnionExample200JSONResponse0 = string + func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 489adcae13..44d017dbd8 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -986,6 +986,8 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } +type UnionExample200JSONResponse0 = string + func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 028b8073bc..13c5969597 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -1102,6 +1102,8 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } +type UnionExample200JSONResponse0 = string + func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index e58751b75f..2034ce7be7 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -1097,6 +1097,8 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } +type UnionExample200JSONResponse0 = string + func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 5814ad1c3a..a686787c13 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -70,6 +70,10 @@ } {{end}} + {{- range .Schema.AdditionalTypes}} + type {{.TypeName}} {{if .IsAlias }}={{end}} {{.Schema.TypeDecl}} + {{- end}} + func (response {{$receiverTypeName}}) Visit{{$opid}}Response(w http.ResponseWriter) error { {{if eq .NameTag "Multipart" -}} writer := multipart.NewWriter(w) From 070fa9306958016ddc72152ed235b2e7067b5743 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 22 Apr 2026 14:25:40 -0700 Subject: [PATCH 37/62] Update YAML package where possible (#2333) Fixes: #2310 All generated and example code now uses go.yaml.in/yaml/v3, however, our own yaml loading is still forced to use an older version due to the yaml overlay package. --- cmd/oapi-codegen/oapi-codegen.go | 20 ++++++++++++++------ examples/authenticated-api/stdhttp/go.mod | 2 +- examples/authenticated-api/stdhttp/go.sum | 2 ++ examples/go.mod | 2 +- examples/go.sum | 2 ++ examples/minimal-server/stdhttp/go.mod | 2 +- examples/minimal-server/stdhttp/go.sum | 2 ++ examples/petstore-expanded/echo-v5/go.mod | 2 +- examples/petstore-expanded/echo-v5/go.sum | 2 ++ examples/petstore-expanded/stdhttp/go.mod | 2 +- examples/petstore-expanded/stdhttp/go.sum | 2 ++ go.mod | 2 +- go.sum | 2 ++ internal/test/go.mod | 2 +- internal/test/go.sum | 2 ++ internal/test/parameters/echov5/go.mod | 2 +- internal/test/parameters/echov5/go.sum | 2 ++ internal/test/schemas/schemas.gen.go | 2 +- internal/test/strict-server/stdhttp/go.mod | 2 +- internal/test/strict-server/stdhttp/go.sum | 2 ++ pkg/codegen/templates/imports.tmpl | 2 +- 21 files changed, 43 insertions(+), 17 deletions(-) diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go index 777697b7b8..604c0b3f0f 100644 --- a/cmd/oapi-codegen/oapi-codegen.go +++ b/cmd/oapi-codegen/oapi-codegen.go @@ -14,6 +14,7 @@ package main import ( + "bytes" "flag" "fmt" "os" @@ -23,7 +24,7 @@ import ( "runtime/debug" "strings" - "gopkg.in/yaml.v2" + "go.yaml.in/yaml/v3" "github.com/oapi-codegen/oapi-codegen/v2/pkg/codegen" "github.com/oapi-codegen/oapi-codegen/v2/pkg/util" @@ -156,10 +157,14 @@ func main() { errExit("error reading config file '%s': %v\n", flagConfigFile, err) } var oldConfig oldConfiguration - oldErr := yaml.UnmarshalStrict(configFile, &oldConfig) + oldDec := yaml.NewDecoder(bytes.NewReader(configFile)) + oldDec.KnownFields(true) + oldErr := oldDec.Decode(&oldConfig) var newConfig configuration - newErr := yaml.UnmarshalStrict(configFile, &newConfig) + newDec := yaml.NewDecoder(bytes.NewReader(configFile)) + newDec.KnownFields(true) + newErr := newDec.Decode(&newConfig) // If one of the two files parses, but the other fails, we know the // answer. @@ -281,11 +286,14 @@ func main() { // If the user asked to output configuration, output it to stdout and exit if flagOutputConfig { - buf, err := yaml.Marshal(opts) - if err != nil { + var buf bytes.Buffer + enc := yaml.NewEncoder(&buf) + enc.SetIndent(2) + if err := enc.Encode(opts); err != nil { errExit("error YAML marshaling configuration: %v\n", err) } - fmt.Print(string(buf)) + _ = enc.Close() + fmt.Print(buf.String()) return } diff --git a/examples/authenticated-api/stdhttp/go.mod b/examples/authenticated-api/stdhttp/go.mod index d78e8862e0..31580ce4bd 100644 --- a/examples/authenticated-api/stdhttp/go.mod +++ b/examples/authenticated-api/stdhttp/go.mod @@ -40,12 +40,12 @@ require ( github.com/valyala/fastjson v1.6.7 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.46.0 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/authenticated-api/stdhttp/go.sum b/examples/authenticated-api/stdhttp/go.sum index de52d10215..8b6ac5870d 100644 --- a/examples/authenticated-api/stdhttp/go.sum +++ b/examples/authenticated-api/stdhttp/go.sum @@ -126,6 +126,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/examples/go.mod b/examples/go.mod index f0833793ce..547b7aaf10 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -111,6 +111,7 @@ require ( github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/yosssi/ace v0.0.5 // indirect go.uber.org/mock v0.5.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.20.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect @@ -123,6 +124,5 @@ require ( golang.org/x/tools v0.42.0 // indirect google.golang.org/protobuf v1.36.9 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index 5777a31fe3..df0f0883a7 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -320,6 +320,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/examples/minimal-server/stdhttp/go.mod b/examples/minimal-server/stdhttp/go.mod index 362bef5c56..c5b745f440 100644 --- a/examples/minimal-server/stdhttp/go.mod +++ b/examples/minimal-server/stdhttp/go.mod @@ -21,10 +21,10 @@ require ( github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/minimal-server/stdhttp/go.sum b/examples/minimal-server/stdhttp/go.sum index bb4e53d852..b20ab9fdc9 100644 --- a/examples/minimal-server/stdhttp/go.sum +++ b/examples/minimal-server/stdhttp/go.sum @@ -97,6 +97,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/examples/petstore-expanded/echo-v5/go.mod b/examples/petstore-expanded/echo-v5/go.mod index 3a9a5d3ef9..7c1c597790 100644 --- a/examples/petstore-expanded/echo-v5/go.mod +++ b/examples/petstore-expanded/echo-v5/go.mod @@ -32,11 +32,11 @@ require ( github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/petstore-expanded/echo-v5/go.sum b/examples/petstore-expanded/echo-v5/go.sum index a653a1f09f..71eb695fb0 100644 --- a/examples/petstore-expanded/echo-v5/go.sum +++ b/examples/petstore-expanded/echo-v5/go.sum @@ -114,6 +114,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/examples/petstore-expanded/stdhttp/go.mod b/examples/petstore-expanded/stdhttp/go.mod index 0a642f935f..998aff9e8e 100644 --- a/examples/petstore-expanded/stdhttp/go.mod +++ b/examples/petstore-expanded/stdhttp/go.mod @@ -32,10 +32,10 @@ require ( github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/petstore-expanded/stdhttp/go.sum b/examples/petstore-expanded/stdhttp/go.sum index b5ae3a9f9f..d1e7ef7d53 100644 --- a/examples/petstore-expanded/stdhttp/go.sum +++ b/examples/petstore-expanded/stdhttp/go.sum @@ -114,6 +114,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/go.mod b/go.mod index 4d5e7aff80..b2a9469a48 100644 --- a/go.mod +++ b/go.mod @@ -8,10 +8,10 @@ require ( github.com/getkin/kin-openapi v0.135.0 github.com/speakeasy-api/openapi v1.19.2 github.com/stretchr/testify v1.11.1 + go.yaml.in/yaml/v3 v3.0.4 golang.org/x/mod v0.33.0 golang.org/x/text v0.34.0 golang.org/x/tools v0.42.0 - gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index bb4e53d852..b20ab9fdc9 100644 --- a/go.sum +++ b/go.sum @@ -97,6 +97,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/internal/test/go.mod b/internal/test/go.mod index 88b0357176..19764e22c9 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -18,7 +18,7 @@ require ( github.com/oapi-codegen/runtime v1.4.0 github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 - gopkg.in/yaml.v2 v2.4.0 + go.yaml.in/yaml/v3 v3.0.4 ) require ( diff --git a/internal/test/go.sum b/internal/test/go.sum index 969bd3f82f..b366040590 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -293,6 +293,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/internal/test/parameters/echov5/go.mod b/internal/test/parameters/echov5/go.mod index ee22f25588..ee133844b5 100644 --- a/internal/test/parameters/echov5/go.mod +++ b/internal/test/parameters/echov5/go.mod @@ -32,10 +32,10 @@ require ( github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/test/parameters/echov5/go.sum b/internal/test/parameters/echov5/go.sum index 4b3a1c089e..67fc9e2b1b 100644 --- a/internal/test/parameters/echov5/go.sum +++ b/internal/test/parameters/echov5/go.sum @@ -110,6 +110,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index fe10c8c7eb..bbfbfa3a0a 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -17,7 +17,7 @@ import ( "path" "strings" - "gopkg.in/yaml.v2" + "go.yaml.in/yaml/v3" "github.com/getkin/kin-openapi/openapi3" "github.com/labstack/echo/v4" diff --git a/internal/test/strict-server/stdhttp/go.mod b/internal/test/strict-server/stdhttp/go.mod index 41acd1741f..4f1b9151ca 100644 --- a/internal/test/strict-server/stdhttp/go.mod +++ b/internal/test/strict-server/stdhttp/go.mod @@ -33,10 +33,10 @@ require ( github.com/speakeasy-api/openapi v1.19.2 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/test/strict-server/stdhttp/go.sum b/internal/test/strict-server/stdhttp/go.sum index 5a7589c118..06ee6318c1 100644 --- a/internal/test/strict-server/stdhttp/go.sum +++ b/internal/test/strict-server/stdhttp/go.sum @@ -110,6 +110,8 @@ github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/pkg/codegen/templates/imports.tmpl b/pkg/codegen/templates/imports.tmpl index 8c76dad36d..4c6260006b 100644 --- a/pkg/codegen/templates/imports.tmpl +++ b/pkg/codegen/templates/imports.tmpl @@ -15,7 +15,7 @@ import ( "encoding/xml" "errors" "fmt" - "gopkg.in/yaml.v2" + "go.yaml.in/yaml/v3" "io" "os" "mime" From dd7d133b0d51a931bd1ad88d1d57fbd25dcc71e7 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 23 Apr 2026 10:42:38 -0700 Subject: [PATCH 38/62] Flagify enum validator generation (#2334) Add an `output-options.skip-enum-validate` flag that suppresses the `Valid()` method generated on enum types. The method is still emitted by default; users whose code defines its own `Valid()` on the same type can now opt out instead of seeing a compile-time conflict. Relates to PR #2227, which introduced the `Valid()` method. Co-authored-by: Claude Opus 4.7 (1M context) --- configuration-schema.json | 4 ++++ pkg/codegen/codegen.go | 5 ++++- pkg/codegen/configuration.go | 6 ++++++ pkg/codegen/schema.go | 3 +++ pkg/codegen/templates/constants.tmpl | 3 ++- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/configuration-schema.json b/configuration-schema.json index cf5cb3b71c..ae58297f62 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -135,6 +135,10 @@ "type": "boolean", "description": "Whether to skip pruning unused components on the generated code" }, + "skip-enum-validate": { + "type": "boolean", + "description": "Whether to skip generation of the Valid() method on enum types" + }, "include-tags": { "type": "array", "description": "Only include operations that have one of these tags. Ignored when empty.", diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 4542635733..65b97e9c0d 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -1045,7 +1045,10 @@ func GenerateEnums(t *template.Template, types []TypeDefinition) (string, error) // Now see if enums conflict with any non-enum typenames - return GenerateTemplates([]string{"constants.tmpl"}, t, Constants{EnumDefinitions: enums}) + return GenerateTemplates([]string{"constants.tmpl"}, t, Constants{ + EnumDefinitions: enums, + SkipEnumValidate: globalState.options.OutputOptions.SkipEnumValidate, + }) } // GenerateImports generates our import statements and package definition. diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 724444690a..4652640954 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -319,6 +319,12 @@ type OutputOptions struct { SkipFmt bool `yaml:"skip-fmt,omitempty"` // Whether to skip pruning unused components on the generated code SkipPrune bool `yaml:"skip-prune,omitempty"` + // SkipEnumValidate disables the generation of the `Valid()` method on + // enum types. By default each generated enum type includes a `Valid() + // bool` method which returns true when the value matches one of the + // defined constants; set this to true to suppress that method when it + // conflicts with user-defined methods of the same name. + SkipEnumValidate bool `yaml:"skip-enum-validate,omitempty"` // Only include operations that have one of these tags. Ignored when empty. IncludeTags []string `yaml:"include-tags,omitempty"` // Exclude operations that have one of these tags. Ignored when empty. diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 167b6c627a..c1ce7708d1 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -200,6 +200,9 @@ type Constants struct { SecuritySchemeProviderNames []string // EnumDefinitions holds type and value information for all enums EnumDefinitions []EnumDefinition + // SkipEnumValidate suppresses generation of the `Valid()` method on + // enum types. Mirrors OutputOptions.SkipEnumValidate. + SkipEnumValidate bool } // TypeDefinition describes a Go type definition in generated code. diff --git a/pkg/codegen/templates/constants.tmpl b/pkg/codegen/templates/constants.tmpl index df434e5377..07a03a2a38 100644 --- a/pkg/codegen/templates/constants.tmpl +++ b/pkg/codegen/templates/constants.tmpl @@ -12,7 +12,7 @@ const ( {{$name}} {{$Enum.TypeName}} = {{$Enum.ValueWrapper}}{{$value}}{{$Enum.ValueWrapper -}} {{end}} ) - +{{if not $.SkipEnumValidate}} // Valid indicates whether the value is a known member of the {{$Enum.TypeName}} enum. func (e {{$Enum.TypeName}}) Valid() bool { switch e { @@ -23,3 +23,4 @@ func (e {{$Enum.TypeName}}) Valid() bool { } } {{end}} +{{end}} From bd48f0c25298ef7644b2383206d899197214687d Mon Sep 17 00:00:00 2001 From: Nelz Date: Thu, 23 Apr 2026 14:29:55 -0700 Subject: [PATCH 39/62] Bug Report: demonstration of overlays and allOf not playing together nicely (#2087) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * demonstration of overlays and allOf not playing together nicely * Reorganize bug test case Relocate the overlay+allOf regression reproduction from examples/anyof-allof-oneof/ to internal/test/extensions/allof-merge-extensions/. The examples/ directory is for happy-path usage, not regression artifacts. The submitter's overlay.yaml, overlays.go, and overlays_test.go are moved via git rename (preserving per-line blame); package renamed to match new directory. examples/anyof-allof-oneof/ reverts to a clean anyOf/allOf/oneOf usage example. The bug is tracked at https://github.com/oapi-codegen/oapi-codegen/issues/2335 and is unrelated to overlays — it's in the allOf+x-go-type interaction in pkg/codegen/schema.go and pkg/codegen/merge_schemas.go. Co-Authored-By: Claude Opus 4.7 (1M context) * fix: honor x-go-type on allOf schemas, stop extension leakage (#2335) Two bugs were interacting to silently drop user intent: 1. In GenerateGoSchema, the `allOf` branch early-returned before the `x-go-type` check, so an outer `allOf` schema's own `x-go-type` was ignored. The documented contract ("completely override the definition of this schema") was violated whenever the schema used `allOf`. Fix: move the `x-go-type` check above the `allOf` branch. 2. In mergeOpenapiSchemas, extensions from all allOf members were blindly unioned into the merged schema's extensions. When a member's extensions included an identity-bound directive like `x-go-type`, that directive would leak up and become the merged schema's alias target -- e.g. `Client` with `x-go-type: OverlayClient` composed with `{properties:{id}}` via `allOf` would emit `type ClientWithId = OverlayClient`, silently dropping the Id field. The naive fix of dropping all extensions breaks the common "$ref + sibling extension" idiom (see issue #1957), where allOf is used not for composition but as a workaround for OpenAPI 3.0's $ref-sibling restriction to attach extensions to a ref. Fix: in mergeSchemas, detect which of the two uses applies by checking whether any allOf member is extension-only. If so (decorator idiom), extensions flow through as before. If not (real composition), drop extensions from the merged result -- each source schema's extensions belong to that schema, not to the composed type. Regression test lives in internal/test/extensions/allof-merge-extensions/. Co-Authored-By: Claude Opus 4.7 (1M context) * Implement Greptile suggestions Three review findings addressed on top of the previous fix commit: 1. Narrow the non-decorator extension clearing from "wipe everything" to targeted delete() calls for x-go-type, x-go-type-name, and x-go-type-import. User-defined schema-level extensions and any other non-identity directives now survive allOf composition -- we only have concrete evidence of incorrect aliasing for the identity-bound three. 2. Tighten isExtensionOnlySchema via a zero-value approach. Zero out Extensions plus the documentary/metadata fields that don't affect the generated Go type (Title, Description, Default, Example, ExternalDocs, Deprecated, ReadOnly, WriteOnly, AllowEmptyValue, XML) and the kin-openapi Origin tracker, then reflect.DeepEqual against the zero Schema. Shorter, and default-safe against future kin-openapi field additions: any new structural field would be non-zero and correctly disqualify decorator classification. 3. Extend the regression test to cover the harder Fix 2 path. The original scenario had x-go-type on both Client and ClientWithId, which Fix 1 alone makes pass. New schemas BaseOnly/DerivedNoOverride exercise the case where only the base schema has an x-go-type overlay -- the derived schema must still be emitted as its own struct (with both Name and Extra fields) rather than aliased to OverlayBaseOnly. The struct literal in TestBaseOnlyOverlay won't compile under the buggy codegen because OverlayBaseOnly has no Extra field, giving the test a compile-time check in addition to the runtime assertion. Co-Authored-By: Claude Opus 4.7 (1M context) * Defensively clone extensions before deleting identity keys The delete() calls in mergeSchemas operated on schema.Extensions directly. In the current code this is safe: valueWithPropagatedRef returns a shallow struct copy whose Extensions map is shared with the caller, but mergeOpenapiSchemas always reallocates Extensions before merging, and the n>=2 guard ensures that reallocation has happened by the time we reach the delete. The delete thus operates on a fresh map, not the caller's shared one. That safety is an invariant held by two separate pieces of code (the n>=1 short-circuit, and mergeOpenapiSchemas' make()), neither of which is obvious from reading the delete. Cloning the map before mutating makes the non-aliasing explicit locally and keeps the code correct even if either piece changes (e.g. an allocation-skipping optimization in mergeOpenapiSchemas). maps.Clone(nil) returns nil and delete(nil, ...) is a no-op, so no nil-guard is needed. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.7 (1M context) --- .../allof_merge_extensions.gen.go | 19 ++++ .../allof-merge-extensions/config.yaml | 9 ++ .../allof-merge-extensions/generate.go | 3 + .../allof-merge-extensions/overlay.yaml | 14 +++ .../allof-merge-extensions/overlays.go | 20 +++++ .../allof-merge-extensions/overlays_test.go | 38 ++++++++ .../allof-merge-extensions/spec.yaml | 43 +++++++++ pkg/codegen/merge_schemas.go | 87 +++++++++++++++++++ pkg/codegen/schema.go | 27 +++--- 9 files changed, 247 insertions(+), 13 deletions(-) create mode 100644 internal/test/extensions/allof-merge-extensions/allof_merge_extensions.gen.go create mode 100644 internal/test/extensions/allof-merge-extensions/config.yaml create mode 100644 internal/test/extensions/allof-merge-extensions/generate.go create mode 100644 internal/test/extensions/allof-merge-extensions/overlay.yaml create mode 100644 internal/test/extensions/allof-merge-extensions/overlays.go create mode 100644 internal/test/extensions/allof-merge-extensions/overlays_test.go create mode 100644 internal/test/extensions/allof-merge-extensions/spec.yaml diff --git a/internal/test/extensions/allof-merge-extensions/allof_merge_extensions.gen.go b/internal/test/extensions/allof-merge-extensions/allof_merge_extensions.gen.go new file mode 100644 index 0000000000..642a693039 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/allof_merge_extensions.gen.go @@ -0,0 +1,19 @@ +// Package allofmergeextensions 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 allofmergeextensions + +// BaseOnly defines model for BaseOnly. +type BaseOnly = OverlayBaseOnly + +// Client defines model for Client. +type Client = OverlayClient + +// ClientWithId defines model for ClientWithId. +type ClientWithId = OverlayClientWithId + +// DerivedNoOverride defines model for DerivedNoOverride. +type DerivedNoOverride struct { + Extra string `json:"extra"` + Name string `json:"name"` +} diff --git a/internal/test/extensions/allof-merge-extensions/config.yaml b/internal/test/extensions/allof-merge-extensions/config.yaml new file mode 100644 index 0000000000..5b8d45626e --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/config.yaml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: allofmergeextensions +generate: + models: true +output: allof_merge_extensions.gen.go +output-options: + skip-prune: true + overlay: + path: overlay.yaml diff --git a/internal/test/extensions/allof-merge-extensions/generate.go b/internal/test/extensions/allof-merge-extensions/generate.go new file mode 100644 index 0000000000..04f81f1634 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/generate.go @@ -0,0 +1,3 @@ +package allofmergeextensions + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/allof-merge-extensions/overlay.yaml b/internal/test/extensions/allof-merge-extensions/overlay.yaml new file mode 100644 index 0000000000..dec7115862 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/overlay.yaml @@ -0,0 +1,14 @@ +overlay: 1.0.0 +info: + title: "Example to indicate how to use the OpenAPI Overlay specification (https://github.com/OAI/Overlay-Specification)" + version: 1.0.0 +actions: + - target: $.components.schemas.Client + update: + x-go-type: OverlayClient + - target: $.components.schemas.ClientWithId + update: + x-go-type: OverlayClientWithId + - target: $.components.schemas.BaseOnly + update: + x-go-type: OverlayBaseOnly diff --git a/internal/test/extensions/allof-merge-extensions/overlays.go b/internal/test/extensions/allof-merge-extensions/overlays.go new file mode 100644 index 0000000000..c2c4c37077 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/overlays.go @@ -0,0 +1,20 @@ +package allofmergeextensions + +// OverlayClient defines model for OverlayClient. +type OverlayClient struct { + Name string `json:"name"` +} + +// OverlayClientWithId defines model for OverlayClientWithId. +type OverlayClientWithId struct { + Id int `json:"id"` + Name string `json:"name"` +} + +// OverlayBaseOnly is the user-provided override for the BaseOnly schema. +// DerivedNoOverride composes BaseOnly via allOf and must NOT be aliased +// to this type — it has to remain its own struct so the Extra field is +// preserved. +type OverlayBaseOnly struct { + Name string `json:"name"` +} diff --git a/internal/test/extensions/allof-merge-extensions/overlays_test.go b/internal/test/extensions/allof-merge-extensions/overlays_test.go new file mode 100644 index 0000000000..33b8c72f58 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/overlays_test.go @@ -0,0 +1,38 @@ +package allofmergeextensions + +import "testing" + +func TestAllOfOverlay(t *testing.T) { + var inner any = Client{} + _, ok := inner.(OverlayClient) + if !ok { + t.Errorf("expected Client to be of type OverlayClient") + } + + var outer any = ClientWithId{} + _, ok = outer.(OverlayClientWithId) + if !ok { + t.Errorf("expected ClientWithId to be of type OverlayClientWithId") + } +} + +// TestBaseOnlyOverlay covers the harder regression path: when only the +// base schema has x-go-type (via overlay) and the derived allOf schema +// has no override of its own, the derived schema must still be emitted +// as a distinct struct containing all composed fields. The previous +// bug leaked BaseOnly's x-go-type up through the allOf merge, producing +// `type DerivedNoOverride = OverlayBaseOnly` and silently dropping the +// Extra field. The struct literal below would fail to compile under +// the buggy codegen because OverlayBaseOnly has no Extra field. +func TestBaseOnlyOverlay(t *testing.T) { + d := DerivedNoOverride{Name: "x", Extra: "y"} + + var asAny any = d + if _, ok := asAny.(OverlayBaseOnly); ok { + t.Error("DerivedNoOverride must not be aliased to OverlayBaseOnly; composition would drop the Extra field") + } + + if d.Name != "x" || d.Extra != "y" { + t.Errorf("field values not preserved through composed struct: %+v", d) + } +} diff --git a/internal/test/extensions/allof-merge-extensions/spec.yaml b/internal/test/extensions/allof-merge-extensions/spec.yaml new file mode 100644 index 0000000000..f8c6453ef7 --- /dev/null +++ b/internal/test/extensions/allof-merge-extensions/spec.yaml @@ -0,0 +1,43 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Regression test for allOf + x-go-type interaction (issue #2335) +components: + schemas: + Client: + type: object + required: + - name + properties: + name: + type: string + ClientWithId: + allOf: + - $ref: '#/components/schemas/Client' + - properties: + id: + type: integer + required: + - id + + # Second scenario: only the BASE schema receives an x-go-type overlay; + # the derived allOf schema has no override of its own. It must still + # be emitted as a distinct struct (with both Name and Extra), not + # aliased to the base's overlay target. Regression test for the case + # where the codegen used to leak the base's x-go-type up through the + # allOf merge, silently dropping the derived schema's extra fields. + BaseOnly: + type: object + required: + - name + properties: + name: + type: string + DerivedNoOverride: + allOf: + - $ref: '#/components/schemas/BaseOnly' + - properties: + extra: + type: string + required: + - extra diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index 1b21ae3e22..af9a9a8b73 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "maps" + "reflect" "strings" "github.com/getkin/kin-openapi/openapi3" @@ -27,6 +28,35 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) { return GenerateGoSchema(allOf[0], path) } + // Distinguish two uses of allOf: + // + // 1. Decorator idiom — at least one INLINE member (Ref == "") is + // "extension-only" (carries no structural content). This is a + // workaround for OpenAPI 3.0's $ref-sibling restriction: users + // wrap a $ref in allOf to attach extensions like + // x-go-type-skip-optional-pointer (see issue #1957). Here + // extensions are meant to flow through to the result. + // + // 2. Real composition — every member either contributes structural + // content or is a $ref contributing the referenced schema. The + // result is a NEW distinct type, and extensions like x-go-type on + // a source schema do NOT transfer (see issue #2335: Client has + // x-go-type=OverlayClient, but allOf[Client, {properties:{id}}] + // is ClientWithId — a different shape, not OverlayClient). + // + // A $ref member is excluded from the decorator check because it is by + // construction delivering the referenced schema, not "decorating" + // siblings — even if the referenced schema happens to carry only + // extensions, that's a property of the target, not an intent on this + // composition. + decoratorIdiom := false + for _, m := range allOf { + if m.Ref == "" && isExtensionOnlySchema(m.Value) { + decoratorIdiom = true + break + } + } + schema, err := valueWithPropagatedRef(allOf[0]) if err != nil { return Schema{}, err @@ -59,9 +89,66 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) { return Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err) } } + + if !decoratorIdiom { + // Drop only the type-identity directives. Other extensions + // (user-defined x-* metadata, etc.) are preserved — we only + // have concrete evidence that the identity-bound ones cause + // incorrect aliasing across composition. + // + // Clone before mutating: the current merge path always + // reallocates schema.Extensions in mergeOpenapiSchemas before + // we reach here, so the delete is safe today — but the + // defensive copy keeps this correct if that invariant changes + // (e.g. an allocation-skipping optimization). Cost is a small + // map copy on a single code path. + ext := maps.Clone(schema.Extensions) + delete(ext, extPropGoType) + delete(ext, extGoTypeName) + delete(ext, extPropGoImport) + schema.Extensions = ext + } + return GenerateGoSchema(openapi3.NewSchemaRef("", &schema), path) } +// isExtensionOnlySchema reports whether a schema carries only extensions, +// with no structural or constraint-bearing content. Used to detect the +// "$ref + sibling extension" idiom: allOf wrappers whose purpose is +// attaching extensions to a $ref (since OpenAPI 3.0 disallows sibling +// keys next to $ref). +// +// Implementation: zero out every field that doesn't affect the generated +// Go type, then compare to the zero Schema. Anything left over — a Type, +// Properties, Pattern, MinLength, etc. — disqualifies the schema from +// being treated as a pure decorator. This formulation defaults to safe +// behavior if kin-openapi gains new structural fields: they'd be non-zero +// by default and correctly disqualify. +func isExtensionOnlySchema(s *openapi3.Schema) bool { + if s == nil || len(s.Extensions) == 0 { + return false + } + tmp := *s + tmp.Extensions = nil + // Source-tracking metadata from kin-openapi; always non-nil for + // schemas parsed from a file. + tmp.Origin = nil + // Purely documentary / metadata fields. These don't affect the + // generated Go type, so a schema carrying only these plus extensions + // still behaves as a decorator. + tmp.Title = "" + tmp.Description = "" + tmp.Default = nil + tmp.Example = nil + tmp.ExternalDocs = nil + tmp.Deprecated = false + tmp.ReadOnly = false + tmp.WriteOnly = false + tmp.AllowEmptyValue = false + tmp.XML = nil + return reflect.DeepEqual(tmp, openapi3.Schema{}) +} + // valueWithPropagatedRef returns a copy of ref schema with its Properties refs // updated if ref itself is external. Otherwise, return ref.Value as-is. func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) { diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index c1ce7708d1..aba59c63e9 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -328,6 +328,20 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { SkipOptionalPointer: skipOptionalPointer, } + // Check x-go-type, which will completely override the definition of this + // schema with the provided type. This must be checked before AllOf so + // that an override on the outer schema wins over allOf composition. + if extension, ok := schema.Extensions[extPropGoType]; ok { + typeName, err := extTypeName(extension) + if err != nil { + return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) + } + outSchema.GoType = typeName + outSchema.DefineViaAlias = true + + return outSchema, nil + } + // AllOf is interesting, and useful. It's the union of a number of other // schemas. A common usage is to create a union of an object with an ID, // so that in a RESTful paradigm, the Create operation can return @@ -341,19 +355,6 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { return mergedSchema, nil } - // Check x-go-type, which will completely override the definition of this - // schema with the provided type. - if extension, ok := schema.Extensions[extPropGoType]; ok { - typeName, err := extTypeName(extension) - if err != nil { - return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) - } - outSchema.GoType = typeName - outSchema.DefineViaAlias = true - - return outSchema, nil - } - // Schema type and format, eg. string / binary t := schema.Type // Handle objects and empty schemas first as a special case From c6d77f26dab62b8120a611d19651c517d61441b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9cile=20Journeaux?= Date: Thu, 23 Apr 2026 18:08:03 -0400 Subject: [PATCH 40/62] feat(client): Add ContentType() to ClientWithResponses responses (#2173) * feat(client): Add ContentType() to ClientWithResponses responses * Make ContentType() default on Flip the ContentType() method on ClientWithResponses response types from opt-in to default-on. The output option is renamed from `client-response-content-type-function` (enable) to `skip-client-response-content-type` (disable). - pkg/codegen/configuration.go: field renamed to SkipClientResponseContentType - configuration-schema.json: key renamed, description inverted - pkg/codegen/templates/client-with-responses.tmpl: condition inverted - internal/test/issues/issue-240-2149: removed; issue240 restored from upstream/main (original issue 240 bytes-function test is still present and ContentType() is now exercised by every generated client) Regenerated all affected .gen.go files. The resulting diff across generated code is large but purely additive: each response type gains a new ContentType() method; no existing declarations are modified or removed, so downstream users cannot be broken by this change. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.7 (1M context) --- configuration-schema.json | 4 + .../authenticated-api/stdhttp/api/api.gen.go | 16 ++ .../test/any_of/codegen/inline/openapi.gen.go | 8 + .../any_of/codegen/ref_schema/openapi.gen.go | 8 + internal/test/any_of/param/param.gen.go | 8 + internal/test/client/client.gen.go | 64 ++++++ internal/test/issues/issue-1039/client.gen.go | 8 + internal/test/issues/issue-1087/api.gen.go | 8 + internal/test/issues/issue-1180/issue.gen.go | 8 + .../test/issues/issue-1182/pkg1/pkg1.gen.go | 8 + .../test/issues/issue-1189/issue1189.gen.go | 8 + .../issue-1208-1209/issue-multi-json.gen.go | 8 + .../test/issues/issue-1212/pkg1/pkg1.gen.go | 8 + .../issues/issue-1277/content-array.gen.go | 8 + .../test/issues/issue-1298/issue1298.gen.go | 8 + .../test/issues/issue-1397/issue1397.gen.go | 8 + .../issue-1529/strict-echo/issue1529.gen.go | 8 + .../issue-1529/strict-fiber/issue1529.gen.go | 8 + .../issue-1529/strict-iris/issue1529.gen.go | 8 + internal/test/issues/issue-1914/client.gen.go | 16 ++ .../issues/issue-2031/prefer/issue2031.gen.go | 8 + .../test/issues/issue-2190/issue2190.gen.go | 8 + .../test/issues/issue-2238/issue2238.gen.go | 8 + internal/test/issues/issue-312/issue.gen.go | 16 ++ internal/test/issues/issue-52/issue.gen.go | 8 + .../issue-grab_import_names/issue.gen.go | 8 + .../issue-illegal_enum_names/issue.gen.go | 8 + internal/test/issues/issue240/client.gen.go | 16 ++ .../name_conflict_resolution.gen.go | 144 ++++++++++++ .../name_normalizer.gen.go | 8 + .../name_normalizer.gen.go | 8 + .../name_normalizer.gen.go | 8 + .../to-camel-case/name_normalizer.gen.go | 8 + .../unset/name_normalizer.gen.go | 8 + .../test/parameters/client/gen/client.gen.go | 216 ++++++++++++++++++ internal/test/parameters/echov5/client.gen.go | 216 ++++++++++++++++++ internal/test/pathalias/client.gen.go | 16 ++ internal/test/schemas/schemas.gen.go | 80 +++++++ .../test/strict-server/client/client.gen.go | 112 +++++++++ pkg/codegen/configuration.go | 3 + .../templates/client-with-responses.tmpl | 11 + 41 files changed, 1146 insertions(+) diff --git a/configuration-schema.json b/configuration-schema.json index ae58297f62..521b251ad9 100644 --- a/configuration-schema.json +++ b/configuration-schema.json @@ -249,6 +249,10 @@ "type": "boolean", "description": "Enable the generation of a `Bytes()` method on response objects for `ClientWithResponses`" }, + "skip-client-response-content-type": { + "type": "boolean", + "description": "Disable the generation of a `ContentType()` method on response objects for `ClientWithResponses`, which is otherwise generated by default." + }, "prefer-skip-optional-pointer": { "type": "boolean", "description": "Allows defining at a global level whether to omit the pointer for a type to indicate that the field/type is optional. This is the same as adding `x-go-type-skip-optional-pointer` to each field (manually, or using an OpenAPI Overlay). A field can set `x-go-type-skip-optional-pointer: false` to still require the optional pointer.", diff --git a/examples/authenticated-api/stdhttp/api/api.gen.go b/examples/authenticated-api/stdhttp/api/api.gen.go index b370659441..5a83732c25 100644 --- a/examples/authenticated-api/stdhttp/api/api.gen.go +++ b/examples/authenticated-api/stdhttp/api/api.gen.go @@ -310,6 +310,14 @@ func (r ListThingsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ListThingsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type AddThingResponse struct { Body []byte HTTPResponse *http.Response @@ -332,6 +340,14 @@ func (r AddThingResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r AddThingResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ListThingsWithResponse request returning *ListThingsResponse func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { rsp, err := c.ListThings(ctx, reqEditors...) diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index 3f85d9bc2f..b837299d1a 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -238,6 +238,14 @@ func (r GetPetsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetPetsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetPetsWithResponse request returning *GetPetsResponse func (c *ClientWithResponses) GetPetsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetPetsResponse, error) { rsp, err := c.GetPets(ctx, reqEditors...) diff --git a/internal/test/any_of/codegen/ref_schema/openapi.gen.go b/internal/test/any_of/codegen/ref_schema/openapi.gen.go index 05d763e6ac..0aa30cd67f 100644 --- a/internal/test/any_of/codegen/ref_schema/openapi.gen.go +++ b/internal/test/any_of/codegen/ref_schema/openapi.gen.go @@ -332,6 +332,14 @@ func (r GetPetsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetPetsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetPetsWithResponse request returning *GetPetsResponse func (c *ClientWithResponses) GetPetsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetPetsResponse, error) { rsp, err := c.GetPets(ctx, reqEditors...) diff --git a/internal/test/any_of/param/param.gen.go b/internal/test/any_of/param/param.gen.go index 825bafeefd..694d466b9d 100644 --- a/internal/test/any_of/param/param.gen.go +++ b/internal/test/any_of/param/param.gen.go @@ -396,6 +396,14 @@ func (r GetTestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetTestWithResponse request returning *GetTestResponse func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { rsp, err := c.GetTest(ctx, params, reqEditors...) diff --git a/internal/test/client/client.gen.go b/internal/test/client/client.gen.go index 13fe998b9a..7a26ea68a2 100644 --- a/internal/test/client/client.gen.go +++ b/internal/test/client/client.gen.go @@ -627,6 +627,14 @@ func (r PostBothResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostBothResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetBothResponse struct { Body []byte HTTPResponse *http.Response @@ -648,6 +656,14 @@ func (r GetBothResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetBothResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostJsonResponse struct { Body []byte HTTPResponse *http.Response @@ -669,6 +685,14 @@ func (r PostJsonResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostJsonResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetJsonResponse struct { Body []byte HTTPResponse *http.Response @@ -690,6 +714,14 @@ func (r GetJsonResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetJsonResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostOtherResponse struct { Body []byte HTTPResponse *http.Response @@ -711,6 +743,14 @@ func (r PostOtherResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostOtherResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetOtherResponse struct { Body []byte HTTPResponse *http.Response @@ -732,6 +772,14 @@ func (r GetOtherResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetOtherResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetJsonWithTrailingSlashResponse struct { Body []byte HTTPResponse *http.Response @@ -753,6 +801,14 @@ func (r GetJsonWithTrailingSlashResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetJsonWithTrailingSlashResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostVendorJsonResponse struct { Body []byte HTTPResponse *http.Response @@ -774,6 +830,14 @@ func (r PostVendorJsonResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostVendorJsonResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // PostBothWithBodyWithResponse request with arbitrary body returning *PostBothResponse func (c *ClientWithResponses) PostBothWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostBothResponse, error) { rsp, err := c.PostBothWithBody(ctx, contentType, body, reqEditors...) diff --git a/internal/test/issues/issue-1039/client.gen.go b/internal/test/issues/issue-1039/client.gen.go index 43cca8d279..63ef866784 100644 --- a/internal/test/issues/issue-1039/client.gen.go +++ b/internal/test/issues/issue-1039/client.gen.go @@ -227,6 +227,14 @@ func (r ExamplePatchResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ExamplePatchResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ExamplePatchWithBodyWithResponse request with arbitrary body returning *ExamplePatchResponse func (c *ClientWithResponses) ExamplePatchWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExamplePatchResponse, error) { rsp, err := c.ExamplePatchWithBody(ctx, contentType, body, reqEditors...) diff --git a/internal/test/issues/issue-1087/api.gen.go b/internal/test/issues/issue-1087/api.gen.go index cf944315f5..dcbcca53ea 100644 --- a/internal/test/issues/issue-1087/api.gen.go +++ b/internal/test/issues/issue-1087/api.gen.go @@ -225,6 +225,14 @@ func (r GetThingsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetThingsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetThingsWithResponse request returning *GetThingsResponse func (c *ClientWithResponses) GetThingsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetThingsResponse, error) { rsp, err := c.GetThings(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1180/issue.gen.go b/internal/test/issues/issue-1180/issue.gen.go index dd7f244904..37499ca5cc 100644 --- a/internal/test/issues/issue-1180/issue.gen.go +++ b/internal/test/issues/issue-1180/issue.gen.go @@ -211,6 +211,14 @@ func (r GetSimplePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimplePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetSimplePrimitiveWithResponse request returning *GetSimplePrimitiveResponse func (c *ClientWithResponses) GetSimplePrimitiveWithResponse(ctx context.Context, param string, reqEditors ...RequestEditorFn) (*GetSimplePrimitiveResponse, error) { rsp, err := c.GetSimplePrimitive(ctx, param, reqEditors...) diff --git a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go index 4773438107..c5111c09d2 100644 --- a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go @@ -205,6 +205,14 @@ func (r TestGetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestGetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestGetWithResponse request returning *TestGetResponse func (c *ClientWithResponses) TestGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestGetResponse, error) { rsp, err := c.TestGet(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1189/issue1189.gen.go b/internal/test/issues/issue-1189/issue1189.gen.go index 8b0aa4c209..e06d16c824 100644 --- a/internal/test/issues/issue-1189/issue1189.gen.go +++ b/internal/test/issues/issue-1189/issue1189.gen.go @@ -416,6 +416,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index 4989ab412c..a5f1602504 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -225,6 +225,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index 643b7e6866..025f02314c 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -207,6 +207,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1277/content-array.gen.go b/internal/test/issues/issue-1277/content-array.gen.go index 41eb70440a..be4983aa29 100644 --- a/internal/test/issues/issue-1277/content-array.gen.go +++ b/internal/test/issues/issue-1277/content-array.gen.go @@ -207,6 +207,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1298/issue1298.gen.go b/internal/test/issues/issue-1298/issue1298.gen.go index 67bb5b92d5..9d156149f6 100644 --- a/internal/test/issues/issue-1298/issue1298.gen.go +++ b/internal/test/issues/issue-1298/issue1298.gen.go @@ -240,6 +240,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithBodyWithResponse request with arbitrary body returning *TestResponse func (c *ClientWithResponses) TestWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.TestWithBody(ctx, contentType, body, reqEditors...) diff --git a/internal/test/issues/issue-1397/issue1397.gen.go b/internal/test/issues/issue-1397/issue1397.gen.go index a799293922..81bfad13c2 100644 --- a/internal/test/issues/issue-1397/issue1397.gen.go +++ b/internal/test/issues/issue-1397/issue1397.gen.go @@ -281,6 +281,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithBodyWithResponse request with arbitrary body returning *TestResponse func (c *ClientWithResponses) TestWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.TestWithBody(ctx, contentType, body, reqEditors...) diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index d392436a89..04180c2821 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -211,6 +211,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index 62cd9ce025..8b1ceac003 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -210,6 +210,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go index 6d03eef9ce..e2a01bd04a 100644 --- a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go @@ -211,6 +211,14 @@ func (r TestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // TestWithResponse request returning *TestResponse func (c *ClientWithResponses) TestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*TestResponse, error) { rsp, err := c.Test(ctx, reqEditors...) diff --git a/internal/test/issues/issue-1914/client.gen.go b/internal/test/issues/issue-1914/client.gen.go index 5628fff078..7af86aac02 100644 --- a/internal/test/issues/issue-1914/client.gen.go +++ b/internal/test/issues/issue-1914/client.gen.go @@ -313,6 +313,14 @@ func (r PostPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostPet1234Response struct { Body []byte HTTPResponse *http.Response @@ -334,6 +342,14 @@ func (r PostPet1234Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostPet1234Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // PostPetWithBodyWithResponse request with arbitrary body returning *PostPetResponse func (c *ClientWithResponses) PostPetWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostPetResponse, error) { rsp, err := c.PostPetWithBody(ctx, contentType, body, reqEditors...) diff --git a/internal/test/issues/issue-2031/prefer/issue2031.gen.go b/internal/test/issues/issue-2031/prefer/issue2031.gen.go index 2dcb3372d1..936ac9f762 100644 --- a/internal/test/issues/issue-2031/prefer/issue2031.gen.go +++ b/internal/test/issues/issue-2031/prefer/issue2031.gen.go @@ -230,6 +230,14 @@ func (r GetTestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetTestWithResponse request returning *GetTestResponse func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { rsp, err := c.GetTest(ctx, params, reqEditors...) diff --git a/internal/test/issues/issue-2190/issue2190.gen.go b/internal/test/issues/issue-2190/issue2190.gen.go index 8cc8570388..0904608db2 100644 --- a/internal/test/issues/issue-2190/issue2190.gen.go +++ b/internal/test/issues/issue-2190/issue2190.gen.go @@ -206,6 +206,14 @@ func (r GetTestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetTestWithResponse request returning *GetTestResponse func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { rsp, err := c.GetTest(ctx, reqEditors...) diff --git a/internal/test/issues/issue-2238/issue2238.gen.go b/internal/test/issues/issue-2238/issue2238.gen.go index 043529ebce..16e923002c 100644 --- a/internal/test/issues/issue-2238/issue2238.gen.go +++ b/internal/test/issues/issue-2238/issue2238.gen.go @@ -236,6 +236,14 @@ func (r GetTestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetTestWithResponse request returning *GetTestResponse func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, params *GetTestParams, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { rsp, err := c.GetTest(ctx, params, reqEditors...) diff --git a/internal/test/issues/issue-312/issue.gen.go b/internal/test/issues/issue-312/issue.gen.go index e49ab36cfe..07102f000b 100644 --- a/internal/test/issues/issue-312/issue.gen.go +++ b/internal/test/issues/issue-312/issue.gen.go @@ -311,6 +311,14 @@ func (r GetPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type ValidatePetsResponse struct { Body []byte HTTPResponse *http.Response @@ -334,6 +342,14 @@ func (r ValidatePetsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ValidatePetsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetPetWithResponse request returning *GetPetResponse func (c *ClientWithResponses) GetPetWithResponse(ctx context.Context, petId string, reqEditors ...RequestEditorFn) (*GetPetResponse, error) { rsp, err := c.GetPet(ctx, petId, reqEditors...) diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go index 2c57dd3223..d79ef78059 100644 --- a/internal/test/issues/issue-52/issue.gen.go +++ b/internal/test/issues/issue-52/issue.gen.go @@ -219,6 +219,14 @@ func (r ExampleGetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ExampleGetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ExampleGetWithResponse request returning *ExampleGetResponse func (c *ClientWithResponses) ExampleGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ExampleGetResponse, error) { rsp, err := c.ExampleGet(ctx, reqEditors...) diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go index ee161c40e9..08af8f82ed 100644 --- a/internal/test/issues/issue-grab_import_names/issue.gen.go +++ b/internal/test/issues/issue-grab_import_names/issue.gen.go @@ -241,6 +241,14 @@ func (r GetFooResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetFooResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetFooWithResponse request returning *GetFooResponse func (c *ClientWithResponses) GetFooWithResponse(ctx context.Context, params *GetFooParams, reqEditors ...RequestEditorFn) (*GetFooResponse, error) { rsp, err := c.GetFoo(ctx, params, reqEditors...) diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go index 1da3d74579..277dc53e3f 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go +++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go @@ -250,6 +250,14 @@ func (r GetFooResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetFooResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetFooWithResponse request returning *GetFooResponse func (c *ClientWithResponses) GetFooWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetFooResponse, error) { rsp, err := c.GetFoo(ctx, reqEditors...) diff --git a/internal/test/issues/issue240/client.gen.go b/internal/test/issues/issue240/client.gen.go index 2953b8ce4a..2ce39f4154 100644 --- a/internal/test/issues/issue240/client.gen.go +++ b/internal/test/issues/issue240/client.gen.go @@ -253,6 +253,14 @@ func (r GetClientResponse) Bytes() []byte { return r.Body } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetClientResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type UpdateClientResponse struct { Body []byte HTTPResponse *http.Response @@ -282,6 +290,14 @@ func (r UpdateClientResponse) Bytes() []byte { return r.Body } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UpdateClientResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetClientWithResponse request returning *GetClientResponse func (c *ClientWithResponses) GetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error) { rsp, err := c.GetClient(ctx, reqEditors...) diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go index bc3fb1ba5a..2c42d3c71c 100644 --- a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -1893,6 +1893,14 @@ func (r ListEntitiesResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ListEntitiesResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostFooResponse struct { Body []byte HTTPResponse *http.Response @@ -1915,6 +1923,14 @@ func (r PostFooResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostFooResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type ListItemsResponse2 struct { Body []byte HTTPResponse *http.Response @@ -1937,6 +1953,14 @@ func (r ListItemsResponse2) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ListItemsResponse2) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type CreateItemResponse2 struct { Body []byte HTTPResponse *http.Response @@ -1959,6 +1983,14 @@ func (r CreateItemResponse2) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r CreateItemResponse2) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type CreateOrderResponse struct { Body []byte HTTPResponse *http.Response @@ -1981,6 +2013,14 @@ func (r CreateOrderResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r CreateOrderResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetOutcomeResponse struct { Body []byte HTTPResponse *http.Response @@ -2003,6 +2043,14 @@ func (r GetOutcomeResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetOutcomeResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostOutcomeResponse struct { Body []byte HTTPResponse *http.Response @@ -2024,6 +2072,14 @@ func (r PostOutcomeResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostOutcomeResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type SendPayloadResponse struct { Body []byte HTTPResponse *http.Response @@ -2046,6 +2102,14 @@ func (r SendPayloadResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r SendPayloadResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type CreatePetResponse struct { Body []byte HTTPResponse *http.Response @@ -2068,6 +2132,14 @@ func (r CreatePetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r CreatePetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type QueryResponse2 struct { Body []byte HTTPResponse *http.Response @@ -2090,6 +2162,14 @@ func (r QueryResponse2) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r QueryResponse2) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetQuxResponse struct { Body []byte HTTPResponse *http.Response @@ -2112,6 +2192,14 @@ func (r GetQuxResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetQuxResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostQuxResponse struct { Body []byte HTTPResponse *http.Response @@ -2133,6 +2221,14 @@ func (r PostQuxResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostQuxResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetRenamedSchemaResponse struct { Body []byte HTTPResponse *http.Response @@ -2155,6 +2251,14 @@ func (r GetRenamedSchemaResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetRenamedSchemaResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostRenamedSchemaResponse struct { Body []byte HTTPResponse *http.Response @@ -2176,6 +2280,14 @@ func (r PostRenamedSchemaResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostRenamedSchemaResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PatchResourceResponse struct { Body []byte HTTPResponse *http.Response @@ -2205,6 +2317,14 @@ func (r PatchResourceResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PatchResourceResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetStatusResponse2 struct { Body []byte HTTPResponse *http.Response @@ -2227,6 +2347,14 @@ func (r GetStatusResponse2) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetStatusResponse2) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetZapResponse struct { Body []byte HTTPResponse *http.Response @@ -2249,6 +2377,14 @@ func (r GetZapResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetZapResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type PostZapResponse struct { Body []byte HTTPResponse *http.Response @@ -2270,6 +2406,14 @@ func (r PostZapResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r PostZapResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ListEntitiesWithResponse request returning *ListEntitiesResponse func (c *ClientWithResponses) ListEntitiesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListEntitiesResponse, error) { rsp, err := c.ListEntities(ctx, reqEditors...) diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go index cbd8ff259e..e27de44070 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go @@ -309,6 +309,14 @@ func (r GetHTTPPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHTTPPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetHTTPPetWithResponse request returning *GetHTTPPetResponse func (c *ClientWithResponses) GetHTTPPetWithResponse(ctx context.Context, petID string, reqEditors ...RequestEditorFn) (*GetHTTPPetResponse, error) { rsp, err := c.GetHTTPPet(ctx, petID, reqEditors...) diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go index 19d2761adc..0b361107a4 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go @@ -309,6 +309,14 @@ func (r GetHttpPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHttpPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetHttpPetWithResponse request returning *GetHttpPetResponse func (c *ClientWithResponses) GetHttpPetWithResponse(ctx context.Context, petId string, reqEditors ...RequestEditorFn) (*GetHttpPetResponse, error) { rsp, err := c.GetHttpPet(ctx, petId, reqEditors...) diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go index ae310f8f39..f69341bea8 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go @@ -309,6 +309,14 @@ func (r GetHTTPPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHTTPPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetHTTPPetWithResponse request returning *GetHTTPPetResponse func (c *ClientWithResponses) GetHTTPPetWithResponse(ctx context.Context, petID string, reqEditors ...RequestEditorFn) (*GetHTTPPetResponse, error) { rsp, err := c.GetHTTPPet(ctx, petID, reqEditors...) diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go index a8696bf99d..b79d538332 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go @@ -309,6 +309,14 @@ func (r GetHttpPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHttpPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetHttpPetWithResponse request returning *GetHttpPetResponse func (c *ClientWithResponses) GetHttpPetWithResponse(ctx context.Context, petId string, reqEditors ...RequestEditorFn) (*GetHttpPetResponse, error) { rsp, err := c.GetHttpPet(ctx, petId, reqEditors...) diff --git a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go index ca724a735b..4e8b5399cd 100644 --- a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go @@ -309,6 +309,14 @@ func (r GetHttpPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHttpPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetHttpPetWithResponse request returning *GetHttpPetResponse func (c *ClientWithResponses) GetHttpPetWithResponse(ctx context.Context, petId string, reqEditors ...RequestEditorFn) (*GetHttpPetResponse, error) { rsp, err := c.GetHttpPet(ctx, petId, reqEditors...) diff --git a/internal/test/parameters/client/gen/client.gen.go b/internal/test/parameters/client/gen/client.gen.go index 3da4e16cf9..d92fda1dc7 100644 --- a/internal/test/parameters/client/gen/client.gen.go +++ b/internal/test/parameters/client/gen/client.gen.go @@ -2079,6 +2079,14 @@ func (r GetContentObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetContentObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetCookieResponse struct { Body []byte HTTPResponse *http.Response @@ -2100,6 +2108,14 @@ func (r GetCookieResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetCookieResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type EnumParamsResponse struct { Body []byte HTTPResponse *http.Response @@ -2121,6 +2137,14 @@ func (r EnumParamsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r EnumParamsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetHeaderResponse struct { Body []byte HTTPResponse *http.Response @@ -2142,6 +2166,14 @@ func (r GetHeaderResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHeaderResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2163,6 +2195,14 @@ func (r GetLabelExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2184,6 +2224,14 @@ func (r GetLabelExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2205,6 +2253,14 @@ func (r GetLabelExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2226,6 +2282,14 @@ func (r GetLabelNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2247,6 +2311,14 @@ func (r GetLabelNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelPrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2268,6 +2340,14 @@ func (r GetLabelPrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelPrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2289,6 +2369,14 @@ func (r GetMatrixExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2310,6 +2398,14 @@ func (r GetMatrixExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2331,6 +2427,14 @@ func (r GetMatrixExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2352,6 +2456,14 @@ func (r GetMatrixNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2373,6 +2485,14 @@ func (r GetMatrixNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixPrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2394,6 +2514,14 @@ func (r GetMatrixPrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixPrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetPassThroughResponse struct { Body []byte HTTPResponse *http.Response @@ -2415,6 +2543,14 @@ func (r GetPassThroughResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetPassThroughResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetDeepObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2436,6 +2572,14 @@ func (r GetDeepObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetDeepObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetQueryDelimitedResponse struct { Body []byte HTTPResponse *http.Response @@ -2457,6 +2601,14 @@ func (r GetQueryDelimitedResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetQueryDelimitedResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetQueryFormResponse struct { Body []byte HTTPResponse *http.Response @@ -2478,6 +2630,14 @@ func (r GetQueryFormResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetQueryFormResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2499,6 +2659,14 @@ func (r GetSimpleExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2520,6 +2688,14 @@ func (r GetSimpleExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2541,6 +2717,14 @@ func (r GetSimpleExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2562,6 +2746,14 @@ func (r GetSimpleNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2583,6 +2775,14 @@ func (r GetSimpleNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimplePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2604,6 +2804,14 @@ func (r GetSimplePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimplePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetStartingWithNumberResponse struct { Body []byte HTTPResponse *http.Response @@ -2625,6 +2833,14 @@ func (r GetStartingWithNumberResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetStartingWithNumberResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetContentObjectWithResponse request returning *GetContentObjectResponse func (c *ClientWithResponses) GetContentObjectWithResponse(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*GetContentObjectResponse, error) { rsp, err := c.GetContentObject(ctx, param, reqEditors...) diff --git a/internal/test/parameters/echov5/client.gen.go b/internal/test/parameters/echov5/client.gen.go index 09ce4a6ff7..a6b498d5ec 100644 --- a/internal/test/parameters/echov5/client.gen.go +++ b/internal/test/parameters/echov5/client.gen.go @@ -1940,6 +1940,14 @@ func (r GetContentObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetContentObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetCookieResponse struct { Body []byte HTTPResponse *http.Response @@ -1961,6 +1969,14 @@ func (r GetCookieResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetCookieResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type EnumParamsResponse struct { Body []byte HTTPResponse *http.Response @@ -1982,6 +1998,14 @@ func (r EnumParamsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r EnumParamsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetHeaderResponse struct { Body []byte HTTPResponse *http.Response @@ -2003,6 +2027,14 @@ func (r GetHeaderResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetHeaderResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2024,6 +2056,14 @@ func (r GetLabelExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2045,6 +2085,14 @@ func (r GetLabelExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2066,6 +2114,14 @@ func (r GetLabelExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2087,6 +2143,14 @@ func (r GetLabelNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2108,6 +2172,14 @@ func (r GetLabelNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetLabelPrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2129,6 +2201,14 @@ func (r GetLabelPrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetLabelPrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2150,6 +2230,14 @@ func (r GetMatrixExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2171,6 +2259,14 @@ func (r GetMatrixExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2192,6 +2288,14 @@ func (r GetMatrixExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2213,6 +2317,14 @@ func (r GetMatrixNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2234,6 +2346,14 @@ func (r GetMatrixNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetMatrixPrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2255,6 +2375,14 @@ func (r GetMatrixPrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetMatrixPrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetPassThroughResponse struct { Body []byte HTTPResponse *http.Response @@ -2276,6 +2404,14 @@ func (r GetPassThroughResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetPassThroughResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetDeepObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2297,6 +2433,14 @@ func (r GetDeepObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetDeepObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetQueryDelimitedResponse struct { Body []byte HTTPResponse *http.Response @@ -2318,6 +2462,14 @@ func (r GetQueryDelimitedResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetQueryDelimitedResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetQueryFormResponse struct { Body []byte HTTPResponse *http.Response @@ -2339,6 +2491,14 @@ func (r GetQueryFormResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetQueryFormResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2360,6 +2520,14 @@ func (r GetSimpleExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2381,6 +2549,14 @@ func (r GetSimpleExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleExplodePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2402,6 +2578,14 @@ func (r GetSimpleExplodePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleExplodePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleNoExplodeArrayResponse struct { Body []byte HTTPResponse *http.Response @@ -2423,6 +2607,14 @@ func (r GetSimpleNoExplodeArrayResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleNoExplodeArrayResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimpleNoExplodeObjectResponse struct { Body []byte HTTPResponse *http.Response @@ -2444,6 +2636,14 @@ func (r GetSimpleNoExplodeObjectResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimpleNoExplodeObjectResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetSimplePrimitiveResponse struct { Body []byte HTTPResponse *http.Response @@ -2465,6 +2665,14 @@ func (r GetSimplePrimitiveResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetSimplePrimitiveResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetStartingWithNumberResponse struct { Body []byte HTTPResponse *http.Response @@ -2486,6 +2694,14 @@ func (r GetStartingWithNumberResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetStartingWithNumberResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetContentObjectWithResponse request returning *GetContentObjectResponse func (c *ClientWithResponses) GetContentObjectWithResponse(ctx context.Context, param ComplexObject, reqEditors ...RequestEditorFn) (*GetContentObjectResponse, error) { rsp, err := c.GetContentObject(ctx, param, reqEditors...) diff --git a/internal/test/pathalias/client.gen.go b/internal/test/pathalias/client.gen.go index d1ee30f777..1339886349 100644 --- a/internal/test/pathalias/client.gen.go +++ b/internal/test/pathalias/client.gen.go @@ -243,6 +243,14 @@ func (r GetTestResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetTestAlias0Response struct { Body []byte HTTPResponse *http.Response @@ -265,6 +273,14 @@ func (r GetTestAlias0Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetTestAlias0Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetTestWithResponse request returning *GetTestResponse func (c *ClientWithResponses) GetTestWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetTestResponse, error) { rsp, err := c.GetTest(ctx, reqEditors...) diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index bbfbfa3a0a..828428a84a 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -828,6 +828,14 @@ func (r EnsureEverythingIsReferencedResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r EnsureEverythingIsReferencedResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue1051Response struct { Body []byte HTTPResponse *http.Response @@ -851,6 +859,14 @@ func (r Issue1051Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue1051Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue127Response struct { Body []byte HTTPResponse *http.Response @@ -876,6 +892,14 @@ func (r Issue127Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue127Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue185Response struct { Body []byte HTTPResponse *http.Response @@ -897,6 +921,14 @@ func (r Issue185Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue185Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue209Response struct { Body []byte HTTPResponse *http.Response @@ -918,6 +950,14 @@ func (r Issue209Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue209Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue30Response struct { Body []byte HTTPResponse *http.Response @@ -939,6 +979,14 @@ func (r Issue30Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue30Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type GetIssues375Response struct { Body []byte HTTPResponse *http.Response @@ -961,6 +1009,14 @@ func (r GetIssues375Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetIssues375Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue41Response struct { Body []byte HTTPResponse *http.Response @@ -982,6 +1038,14 @@ func (r Issue41Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue41Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue9Response struct { Body []byte HTTPResponse *http.Response @@ -1003,6 +1067,14 @@ func (r Issue9Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue9Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type Issue975Response struct { Body []byte HTTPResponse *http.Response @@ -1025,6 +1097,14 @@ func (r Issue975Response) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r Issue975Response) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // EnsureEverythingIsReferencedWithResponse request returning *EnsureEverythingIsReferencedResponse func (c *ClientWithResponses) EnsureEverythingIsReferencedWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*EnsureEverythingIsReferencedResponse, error) { rsp, err := c.EnsureEverythingIsReferenced(ctx, reqEditors...) diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index 66eeb2014c..72a328818a 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -1205,6 +1205,14 @@ func (r JSONExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r JSONExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type MultipartExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1226,6 +1234,14 @@ func (r MultipartExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r MultipartExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type MultipartRelatedExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1247,6 +1263,14 @@ func (r MultipartRelatedExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r MultipartRelatedExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type MultipleRequestAndResponseTypesResponse struct { Body []byte HTTPResponse *http.Response @@ -1269,6 +1293,14 @@ func (r MultipleRequestAndResponseTypesResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r MultipleRequestAndResponseTypesResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type RequiredJSONBodyResponse struct { Body []byte HTTPResponse *http.Response @@ -1291,6 +1323,14 @@ func (r RequiredJSONBodyResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r RequiredJSONBodyResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type RequiredTextBodyResponse struct { Body []byte HTTPResponse *http.Response @@ -1312,6 +1352,14 @@ func (r RequiredTextBodyResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r RequiredTextBodyResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type ReservedGoKeywordParametersResponse struct { Body []byte HTTPResponse *http.Response @@ -1333,6 +1381,14 @@ func (r ReservedGoKeywordParametersResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ReservedGoKeywordParametersResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type ReusableResponsesResponse struct { Body []byte HTTPResponse *http.Response @@ -1355,6 +1411,14 @@ func (r ReusableResponsesResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ReusableResponsesResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type TextExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1376,6 +1440,14 @@ func (r TextExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r TextExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type UnknownExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1397,6 +1469,14 @@ func (r UnknownExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UnknownExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type UnspecifiedContentTypeResponse struct { Body []byte HTTPResponse *http.Response @@ -1418,6 +1498,14 @@ func (r UnspecifiedContentTypeResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UnspecifiedContentTypeResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type URLEncodedExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1439,6 +1527,14 @@ func (r URLEncodedExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r URLEncodedExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type HeadersExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1461,6 +1557,14 @@ func (r HeadersExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r HeadersExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type UnionExampleResponse struct { Body []byte HTTPResponse *http.Response @@ -1487,6 +1591,14 @@ func (r UnionExampleResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UnionExampleResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // JSONExampleWithBodyWithResponse request with arbitrary body returning *JSONExampleResponse func (c *ClientWithResponses) JSONExampleWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*JSONExampleResponse, error) { rsp, err := c.JSONExampleWithBody(ctx, contentType, body, reqEditors...) diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 4652640954..7938aa9fdb 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -371,6 +371,9 @@ type OutputOptions struct { // ClientResponseBytesFunction decides whether to enable the generation of a `Bytes()` method on response objects for `ClientWithResponses` ClientResponseBytesFunction bool `yaml:"client-response-bytes-function,omitempty"` + // SkipClientResponseContentType disables the generation of a `ContentType()` method on response objects for `ClientWithResponses`, which is otherwise generated by default. + SkipClientResponseContentType bool `yaml:"skip-client-response-content-type,omitempty"` + // PreferSkipOptionalPointer allows defining at a global level whether to omit the pointer for a type to indicate that the field/type is optional. // This is the same as adding `x-go-type-skip-optional-pointer` to each field (manually, or using an OpenAPI Overlay) PreferSkipOptionalPointer bool `yaml:"prefer-skip-optional-pointer,omitempty"` diff --git a/pkg/codegen/templates/client-with-responses.tmpl b/pkg/codegen/templates/client-with-responses.tmpl index 3b85500a8d..8b5b670be6 100644 --- a/pkg/codegen/templates/client-with-responses.tmpl +++ b/pkg/codegen/templates/client-with-responses.tmpl @@ -81,6 +81,17 @@ func (r {{genResponseTypeName $opid | ucFirst}}) Bytes() []byte { return r.Body } {{end}} + +{{ if not opts.OutputOptions.SkipClientResponseContentType }} +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r {{genResponseTypeName $opid | ucFirst}}) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} +{{end}} + {{end}} From 097bc33cf46c4cd824e94fc968dd5f3694fc2ff3 Mon Sep 17 00:00:00 2001 From: Paul Mach Date: Fri, 24 Apr 2026 23:13:40 -0700 Subject: [PATCH 41/62] support all x-* extensions and with ref (#1880) * support `x-go-type` and `x-go-type-import` with ref * support all other extensions and with ref * Fix code review feedback Greptile pointed out that we lost a guard on x-go-import, so put it back. * Honor ref-sibling extensions in allOf merge and parameter schemas PR #1880 introduced combinedSchemaExtensions so extensions placed next to a $ref are honored, with ref-side winning over value-side. The helper is wired in at GenerateGoSchema and Property.Extensions, but three other consumers of *openapi3.SchemaRef extensions still read value-side only and silently shadow the ref-side siblings. This commit closes the remaining gaps. * pkg/codegen/merge_schemas.go - valueWithPropagatedRef now folds ref.Extensions into the returned schema's Extensions via combinedSchemaExtensions, so allOf members can carry per-use sibling directives without mutating the referenced schema. Also returns a shallow copy unconditionally with a fresh Extensions map so callers can't back-mutate the source SchemaRef. - mergeAllOf routes each member through valueWithPropagatedRef instead of dereferencing schemaRef.Value directly, so the transitively-flattened nested-allOf path inherits the same fix. - The "real composition drops type-identity extensions" delete block at lines 105-109 is unchanged; it now strips ref-side x-go-type / x-go-type-name / x-go-type-import the same way it strips value-side, since both end up in schema.Extensions under the same keys. The allof-merge-extensions fixture remains bit-identical. * pkg/codegen/operations.go - GenerateParamsTypes uses combinedSchemaExtensions(param.Spec.Schema) when building the *Params struct field's extension map, so a sibling extension on a parameter's $ref schema (e.g. x-omitempty: false next to a $ref) reaches the field. * internal/test/extensions/param-ref-sibling-omitempty/ - New regression fixture exercising the Gap 3 fix: a query parameter whose schema is a $ref with sibling x-omitempty: false now generates json:"filter" instead of json:"filter,omitempty". * internal/test/go.mod - make tidy promotes golang.org/x/time from indirect to direct (used by the x-go-type fixture's generated file from PR #1880). --------- Co-authored-by: Marcin Romaszewicz --- .../param-ref-sibling-omitempty/config.yaml | 8 + .../param-ref-sibling-omitempty/generate.go | 3 + .../param-ref-sibling-omitempty/issue.gen.go | 267 ++++++++++++++++++ .../param-ref-sibling-omitempty/spec.yaml | 22 ++ .../config.yaml | 7 + .../generate.go | 3 + .../issue.gen.go | 17 ++ .../x-go-type-skip-optional-pointer/spec.yaml | 18 ++ .../test/extensions/x-go-type/config.yaml | 7 + .../test/extensions/x-go-type/generate.go | 3 + .../test/extensions/x-go-type/issue.gen.go | 19 ++ internal/test/extensions/x-go-type/spec.yaml | 25 ++ .../x-oapi-codegen-extra-tags/config.yaml | 7 + .../x-oapi-codegen-extra-tags/generate.go | 3 + .../x-oapi-codegen-extra-tags/issue.gen.go | 14 + .../x-oapi-codegen-extra-tags/spec.yaml | 22 ++ .../test/extensions/x-omitempty/config.yaml | 7 + .../test/extensions/x-omitempty/generate.go | 3 + .../test/extensions/x-omitempty/issue.gen.go | 17 ++ .../test/extensions/x-omitempty/spec.yaml | 18 ++ internal/test/go.mod | 2 +- pkg/codegen/codegen.go | 13 +- pkg/codegen/merge_schemas.go | 23 +- pkg/codegen/operations.go | 11 +- pkg/codegen/schema.go | 56 +++- pkg/codegen/utils.go | 21 +- 26 files changed, 586 insertions(+), 30 deletions(-) create mode 100644 internal/test/extensions/param-ref-sibling-omitempty/config.yaml create mode 100644 internal/test/extensions/param-ref-sibling-omitempty/generate.go create mode 100644 internal/test/extensions/param-ref-sibling-omitempty/issue.gen.go create mode 100644 internal/test/extensions/param-ref-sibling-omitempty/spec.yaml create mode 100644 internal/test/extensions/x-go-type-skip-optional-pointer/config.yaml create mode 100644 internal/test/extensions/x-go-type-skip-optional-pointer/generate.go create mode 100644 internal/test/extensions/x-go-type-skip-optional-pointer/issue.gen.go create mode 100644 internal/test/extensions/x-go-type-skip-optional-pointer/spec.yaml create mode 100644 internal/test/extensions/x-go-type/config.yaml create mode 100644 internal/test/extensions/x-go-type/generate.go create mode 100644 internal/test/extensions/x-go-type/issue.gen.go create mode 100644 internal/test/extensions/x-go-type/spec.yaml create mode 100644 internal/test/extensions/x-oapi-codegen-extra-tags/config.yaml create mode 100644 internal/test/extensions/x-oapi-codegen-extra-tags/generate.go create mode 100644 internal/test/extensions/x-oapi-codegen-extra-tags/issue.gen.go create mode 100644 internal/test/extensions/x-oapi-codegen-extra-tags/spec.yaml create mode 100644 internal/test/extensions/x-omitempty/config.yaml create mode 100644 internal/test/extensions/x-omitempty/generate.go create mode 100644 internal/test/extensions/x-omitempty/issue.gen.go create mode 100644 internal/test/extensions/x-omitempty/spec.yaml diff --git a/internal/test/extensions/param-ref-sibling-omitempty/config.yaml b/internal/test/extensions/param-ref-sibling-omitempty/config.yaml new file mode 100644 index 0000000000..0b135b9755 --- /dev/null +++ b/internal/test/extensions/param-ref-sibling-omitempty/config.yaml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: paramrefsiblingomitempty +generate: + models: true + client: true +output: issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/extensions/param-ref-sibling-omitempty/generate.go b/internal/test/extensions/param-ref-sibling-omitempty/generate.go new file mode 100644 index 0000000000..589a73584b --- /dev/null +++ b/internal/test/extensions/param-ref-sibling-omitempty/generate.go @@ -0,0 +1,3 @@ +package paramrefsiblingomitempty + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/param-ref-sibling-omitempty/issue.gen.go b/internal/test/extensions/param-ref-sibling-omitempty/issue.gen.go new file mode 100644 index 0000000000..1cc7a983d3 --- /dev/null +++ b/internal/test/extensions/param-ref-sibling-omitempty/issue.gen.go @@ -0,0 +1,267 @@ +// Package paramrefsiblingomitempty 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 paramrefsiblingomitempty + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// FilterValue defines model for FilterValue. +type FilterValue = string + +// ListThingsParams defines parameters for ListThings. +type ListThingsParams struct { + Filter *FilterValue `form:"filter" json:"filter"` +} + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // ListThings request + ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListThingsRequest(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) +} + +// NewListThingsRequest generates requests for ListThings +func NewListThingsRequest(server string, params *ListThingsParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/things") + 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.Filter != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "filter", *params.Filter, 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 +} + +func (c *Client) 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 *Client) 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 { + // ListThingsWithResponse request + ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) +} + +type ListThingsResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r ListThingsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListThingsResponse) 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 ListThingsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +// ListThingsWithResponse request returning *ListThingsResponse +func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { + rsp, err := c.ListThings(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseListThingsResponse(rsp) +} + +// ParseListThingsResponse parses an HTTP response from a ListThingsWithResponse call +func ParseListThingsResponse(rsp *http.Response) (*ListThingsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListThingsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/extensions/param-ref-sibling-omitempty/spec.yaml b/internal/test/extensions/param-ref-sibling-omitempty/spec.yaml new file mode 100644 index 0000000000..bd4d17cf89 --- /dev/null +++ b/internal/test/extensions/param-ref-sibling-omitempty/spec.yaml @@ -0,0 +1,22 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Regression test for sibling x-omitempty on parameter $ref +paths: + /things: + get: + operationId: listThings + parameters: + - name: filter + in: query + required: false + schema: + $ref: '#/components/schemas/FilterValue' + x-omitempty: false + responses: + '200': + description: OK +components: + schemas: + FilterValue: + type: string diff --git a/internal/test/extensions/x-go-type-skip-optional-pointer/config.yaml b/internal/test/extensions/x-go-type-skip-optional-pointer/config.yaml new file mode 100644 index 0000000000..b2846a10b0 --- /dev/null +++ b/internal/test/extensions/x-go-type-skip-optional-pointer/config.yaml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: xgotypeskipoptionalpointer +generate: + models: true +output: issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/extensions/x-go-type-skip-optional-pointer/generate.go b/internal/test/extensions/x-go-type-skip-optional-pointer/generate.go new file mode 100644 index 0000000000..43f0c15780 --- /dev/null +++ b/internal/test/extensions/x-go-type-skip-optional-pointer/generate.go @@ -0,0 +1,3 @@ +package xgotypeskipoptionalpointer + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/x-go-type-skip-optional-pointer/issue.gen.go b/internal/test/extensions/x-go-type-skip-optional-pointer/issue.gen.go new file mode 100644 index 0000000000..10373fc27e --- /dev/null +++ b/internal/test/extensions/x-go-type-skip-optional-pointer/issue.gen.go @@ -0,0 +1,17 @@ +// Package xgotypeskipoptionalpointer 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 xgotypeskipoptionalpointer + +// Default defines model for Default. +type Default = int + +// SkipOptionalTrue defines model for SkipOptionalTrue. +type SkipOptionalTrue = int + +// SomeObject defines model for SomeObject. +type SomeObject struct { + SkipOptional SkipOptionalTrue `json:"skip_optional,omitempty"` + SkipOptionalNextToRef Default `json:"skip_optional_next_to_ref,omitempty"` + SkipOptionalOverrideToFalse *SkipOptionalTrue `json:"skip_optional_override_to_false,omitempty"` +} diff --git a/internal/test/extensions/x-go-type-skip-optional-pointer/spec.yaml b/internal/test/extensions/x-go-type-skip-optional-pointer/spec.yaml new file mode 100644 index 0000000000..7e4abdca38 --- /dev/null +++ b/internal/test/extensions/x-go-type-skip-optional-pointer/spec.yaml @@ -0,0 +1,18 @@ +components: + schemas: + Default: + type: integer + SkipOptionalTrue: + type: integer + x-go-type-skip-optional-pointer: true + SomeObject: + type: object + properties: + skip_optional: + $ref: '#/components/schemas/SkipOptionalTrue' + skip_optional_override_to_false: + $ref: '#/components/schemas/SkipOptionalTrue' + x-go-type-skip-optional-pointer: false + skip_optional_next_to_ref: + $ref: '#/components/schemas/Default' + x-go-type-skip-optional-pointer: true diff --git a/internal/test/extensions/x-go-type/config.yaml b/internal/test/extensions/x-go-type/config.yaml new file mode 100644 index 0000000000..22d11384c6 --- /dev/null +++ b/internal/test/extensions/x-go-type/config.yaml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: xgotype +generate: + models: true +output: issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/extensions/x-go-type/generate.go b/internal/test/extensions/x-go-type/generate.go new file mode 100644 index 0000000000..32bf4d8403 --- /dev/null +++ b/internal/test/extensions/x-go-type/generate.go @@ -0,0 +1,3 @@ +package xgotype + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/x-go-type/issue.gen.go b/internal/test/extensions/x-go-type/issue.gen.go new file mode 100644 index 0000000000..98de310ce2 --- /dev/null +++ b/internal/test/extensions/x-go-type/issue.gen.go @@ -0,0 +1,19 @@ +// Package xgotype 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 xgotype + +import ( + googleuuid "github.com/google/uuid" + rate "golang.org/x/time/rate" +) + +// SomeInteger defines model for SomeInteger. +type SomeInteger = int + +// SomeObject defines model for SomeObject. +type SomeObject struct { + IntAsRateLimit *rate.Limit `json:"int_as_rate_limit,omitempty"` + IntAsString string `json:"int_as_string"` + IntAsUuid *googleuuid.UUID `json:"int_as_uuid,omitempty"` +} diff --git a/internal/test/extensions/x-go-type/spec.yaml b/internal/test/extensions/x-go-type/spec.yaml new file mode 100644 index 0000000000..fefccfd273 --- /dev/null +++ b/internal/test/extensions/x-go-type/spec.yaml @@ -0,0 +1,25 @@ +components: + schemas: + SomeInteger: + type: integer + x-go-type-import: + name: rate + path: golang.org/x/time/rate + SomeObject: + type: object + required: + - int_as_string + - int_as_big_int + properties: + int_as_string: + $ref: '#/components/schemas/SomeInteger' + x-go-type: string + int_as_rate_limit: + $ref: '#/components/schemas/SomeInteger' + x-go-type: rate.Limit + int_as_uuid: + $ref: '#/components/schemas/SomeInteger' + x-go-type: googleuuid.UUID + x-go-type-import: + path: github.com/google/uuid + name: googleuuid diff --git a/internal/test/extensions/x-oapi-codegen-extra-tags/config.yaml b/internal/test/extensions/x-oapi-codegen-extra-tags/config.yaml new file mode 100644 index 0000000000..58cb1a5395 --- /dev/null +++ b/internal/test/extensions/x-oapi-codegen-extra-tags/config.yaml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: xextratags +generate: + models: true +output: issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/extensions/x-oapi-codegen-extra-tags/generate.go b/internal/test/extensions/x-oapi-codegen-extra-tags/generate.go new file mode 100644 index 0000000000..72bf293b13 --- /dev/null +++ b/internal/test/extensions/x-oapi-codegen-extra-tags/generate.go @@ -0,0 +1,3 @@ +package xextratags + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/x-oapi-codegen-extra-tags/issue.gen.go b/internal/test/extensions/x-oapi-codegen-extra-tags/issue.gen.go new file mode 100644 index 0000000000..804fbff16d --- /dev/null +++ b/internal/test/extensions/x-oapi-codegen-extra-tags/issue.gen.go @@ -0,0 +1,14 @@ +// Package xextratags 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 xextratags + +// Port defines model for Port. +type Port = int + +// SomeObject defines model for SomeObject. +type SomeObject struct { + Port *Port `bson:"port" json:"port,omitempty"` + StartPort *Port `bson:"start_port" json:"start_port,omitempty"` + EndPort *Port `bson:"end_port" json:"end_port,omitempty"` +} diff --git a/internal/test/extensions/x-oapi-codegen-extra-tags/spec.yaml b/internal/test/extensions/x-oapi-codegen-extra-tags/spec.yaml new file mode 100644 index 0000000000..b87d3a21e0 --- /dev/null +++ b/internal/test/extensions/x-oapi-codegen-extra-tags/spec.yaml @@ -0,0 +1,22 @@ +components: + schemas: + Port: + type: integer + x-oapi-codegen-extra-tags: + bson: port + SomeObject: + type: object + properties: + port: + $ref: '#/components/schemas/Port' + x-order: 1 + start_port: + $ref: '#/components/schemas/Port' + x-order: 2 + x-oapi-codegen-extra-tags: + bson: start_port + end_port: + $ref: '#/components/schemas/Port' + x-order: 3 + x-oapi-codegen-extra-tags: + bson: end_port diff --git a/internal/test/extensions/x-omitempty/config.yaml b/internal/test/extensions/x-omitempty/config.yaml new file mode 100644 index 0000000000..d44589c9d8 --- /dev/null +++ b/internal/test/extensions/x-omitempty/config.yaml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: xomitempty +generate: + models: true +output: issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/extensions/x-omitempty/generate.go b/internal/test/extensions/x-omitempty/generate.go new file mode 100644 index 0000000000..084b10e62c --- /dev/null +++ b/internal/test/extensions/x-omitempty/generate.go @@ -0,0 +1,3 @@ +package xomitempty + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/extensions/x-omitempty/issue.gen.go b/internal/test/extensions/x-omitempty/issue.gen.go new file mode 100644 index 0000000000..40e3f0b7fe --- /dev/null +++ b/internal/test/extensions/x-omitempty/issue.gen.go @@ -0,0 +1,17 @@ +// Package xomitempty 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 xomitempty + +// Default defines model for Default. +type Default = int + +// OmitemptyTrue defines model for OmitemptyTrue. +type OmitemptyTrue = int + +// SomeObject defines model for SomeObject. +type SomeObject struct { + Omitempty *OmitemptyTrue `json:"omitempty,omitempty"` + OmitemptyNextToRef *Default `json:"omitempty_next_to_ref,omitempty"` + OmitemptyOverrideToFalse *OmitemptyTrue `json:"omitempty_override_to_false"` +} diff --git a/internal/test/extensions/x-omitempty/spec.yaml b/internal/test/extensions/x-omitempty/spec.yaml new file mode 100644 index 0000000000..3ffe4571a1 --- /dev/null +++ b/internal/test/extensions/x-omitempty/spec.yaml @@ -0,0 +1,18 @@ +components: + schemas: + Default: + type: integer + OmitemptyTrue: + type: integer + x-omitempty: true + SomeObject: + type: object + properties: + omitempty: + $ref: '#/components/schemas/OmitemptyTrue' + omitempty_override_to_false: + $ref: '#/components/schemas/OmitemptyTrue' + x-omitempty: false + omitempty_next_to_ref: + $ref: '#/components/schemas/Default' + x-omitempty: true diff --git a/internal/test/go.mod b/internal/test/go.mod index 19764e22c9..1a1e9b4ed5 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -19,6 +19,7 @@ require ( github.com/oapi-codegen/testutil v1.1.0 github.com/stretchr/testify v1.11.1 go.yaml.in/yaml/v3 v3.0.4 + golang.org/x/time v0.14.0 ) require ( @@ -106,7 +107,6 @@ require ( golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect - golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.42.0 // indirect google.golang.org/protobuf v1.36.9 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 65b97e9c0d..8514ef83e1 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -1334,15 +1334,18 @@ func GetTypeDefinitionsImports(swagger *openapi3.T, excludeSchemas []string) (ma func GoSchemaImports(schemas ...*openapi3.SchemaRef) (map[string]goImport, error) { res := map[string]goImport{} for _, sref := range schemas { - if sref == nil || sref.Value == nil || IsGoTypeReference(sref.Ref) { + if sref == nil { return nil, nil } + if gi, err := ParseGoImportExtension(sref); err != nil { return nil, err - } else { - if gi != nil { - res[gi.String()] = *gi - } + } else if gi != nil { + res[gi.String()] = *gi + } + + if sref.Value == nil || IsGoTypeReference(sref.Ref) { + continue } schemaVal := sref.Value diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index af9a9a8b73..bc887cfa3b 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -149,11 +149,17 @@ func isExtensionOnlySchema(s *openapi3.Schema) bool { return reflect.DeepEqual(tmp, openapi3.Schema{}) } -// valueWithPropagatedRef returns a copy of ref schema with its Properties refs -// updated if ref itself is external. Otherwise, return ref.Value as-is. +// valueWithPropagatedRef returns a copy of ref's schema with its Properties +// refs rewritten when ref itself is external, and with extensions placed +// next to the $ref folded in (ref-side wins over value-side). This is what +// allows allOf members to carry per-use sibling directives without +// mutating the referenced schema. func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) { + schema := *ref.Value + schema.Extensions = combinedSchemaExtensions(ref) + if len(ref.Ref) == 0 || ref.Ref[0] == '#' { - return *ref.Value, nil + return schema, nil } pathParts := strings.Split(ref.Ref, "#") @@ -162,8 +168,6 @@ func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) { } remoteComponent := pathParts[0] - // remote ref - schema := *ref.Value for _, value := range schema.Properties { if len(value.Ref) > 0 && value.Ref[0] == '#' { // local reference, should propagate remote @@ -184,7 +188,14 @@ func mergeAllOf(allOf []*openapi3.SchemaRef, seenSchemaRef map[string]bool) (ope if schemaRef.Ref != "" { seenSchemaRef[schemaRef.Ref] = true } - schema, err = mergeOpenapiSchemas(schema, *schemaRef.Value, true, seenSchemaRef) + // Use valueWithPropagatedRef so sibling extensions on a $ref + // member of a transitively-flattened allOf reach the merged + // schema, matching mergeSchemas' top-level handling. + member, err := valueWithPropagatedRef(schemaRef) + if err != nil { + return openapi3.Schema{}, err + } + schema, err = mergeOpenapiSchemas(schema, member, true, seenSchemaRef) if err != nil { return openapi3.Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err) } diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 8b1a01bd45..ec395284e7 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -1073,11 +1073,14 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition { Schema: param.Schema, }) } - // Merge extensions from the schema level and the parameter level. - // Parameter-level extensions take precedence over schema-level ones. + // Merge extensions, in order of increasing precedence: + // 1. extensions on the referenced schema (param.Spec.Schema.Value) + // 2. extensions placed as siblings of a $ref inside the + // parameter's schema (param.Spec.Schema.Extensions) + // 3. extensions on the Parameter object itself extensions := make(map[string]any) - if param.Spec.Schema != nil && param.Spec.Schema.Value != nil { - maps.Copy(extensions, param.Spec.Schema.Value.Extensions) + if param.Spec.Schema != nil { + maps.Copy(extensions, combinedSchemaExtensions(param.Spec.Schema)) } maps.Copy(extensions, param.Spec.Extensions) prop := Property{ diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index aba59c63e9..f9c7338161 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -3,6 +3,7 @@ package codegen import ( "errors" "fmt" + "maps" "slices" "strings" @@ -291,12 +292,13 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { } schema := sref.Value + extensions := combinedSchemaExtensions(sref) // Check x-go-type-skip-optional-pointer, which will override if the type // should be a pointer or not when the field is optional. // NOTE skipOptionalPointer will be defaulted to the global value, but can be overridden on a per-type/-field basis skipOptionalPointer := globalState.options.OutputOptions.PreferSkipOptionalPointer - if extension, ok := schema.Extensions[extPropGoTypeSkipOptionalPointer]; ok { + if extension, ok := extensions[extPropGoTypeSkipOptionalPointer]; ok { var err error skipOptionalPointer, err = extParsePropGoTypeSkipOptionalPointer(extension) if err != nil { @@ -307,18 +309,32 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // If Ref is set on the SchemaRef, it means that this type is actually a reference to // another type. We're not de-referencing, so simply use the referenced type. if IsGoTypeReference(sref.Ref) { - // Convert the reference path to Go type - refType, err := RefPathToGoType(sref.Ref) - if err != nil { - return Schema{}, fmt.Errorf("error turning reference (%s) into a Go type: %s", - sref.Ref, err) + var refType string + + // check if there is an x-go-type extension next to the $ref and use that over the overrided type. + if extension, ok := sref.Extensions[extPropGoType]; ok { + var ok bool + refType, ok = extension.(string) + if !ok { + return Schema{}, fmt.Errorf("error turning '%s: %v' into string", + extPropGoType, extension) + } + } else { + // Convert the reference path to Go type + var err error + refType, err = RefPathToGoType(sref.Ref) + if err != nil { + return Schema{}, fmt.Errorf("error turning reference (%s) into a Go type: %s", + sref.Ref, err) + } } + return Schema{ GoType: refType, Description: schema.Description, DefineViaAlias: true, - OAPISchema: schema, SkipOptionalPointer: skipOptionalPointer, + OAPISchema: schema, }, nil } @@ -331,7 +347,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // Check x-go-type, which will completely override the definition of this // schema with the provided type. This must be checked before AllOf so // that an override on the outer schema wins over allOf composition. - if extension, ok := schema.Extensions[extPropGoType]; ok { + if extension, ok := extensions[extPropGoType]; ok { typeName, err := extTypeName(extension) if err != nil { return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) @@ -466,6 +482,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { if p.Value != nil { description = p.Value.Description } + prop := Property{ JsonFieldName: pName, Schema: pSchema, @@ -474,7 +491,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { Nullable: p.Value.Nullable, ReadOnly: p.Value.ReadOnly, WriteOnly: p.Value.WriteOnly, - Extensions: p.Value.Extensions, + Extensions: combinedSchemaExtensions(p), Deprecated: p.Value.Deprecated, } outSchema.Properties = append(outSchema.Properties, prop) @@ -500,7 +517,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // Check for x-go-type-name. It behaves much like x-go-type, however, it will // create a type definition for the named type, and use the named type in place // of this schema. - if extension, ok := schema.Extensions[extGoTypeName]; ok { + if extension, ok := extensions[extGoTypeName]; ok { typeName, err := extTypeName(extension) if err != nil { return outSchema, fmt.Errorf("invalid value for %q: %w", extGoTypeName, err) @@ -536,7 +553,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { enumNames := enumValues for _, key := range []string{extEnumVarNames, extEnumNames} { - if extension, ok := schema.Extensions[key]; ok { + if extension, ok := extensions[key]; ok { if extEnumNames, err := extParseEnumVarNames(extension); err == nil { enumNames = extEnumNames break @@ -564,7 +581,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // Allow overriding autogenerated enum type names, since these may // cause conflicts - see https://github.com/oapi-codegen/oapi-codegen/issues/832 var typeName string - if extension, ok := schema.Extensions[extGoTypeName]; ok { + if extension, ok := extensions[extGoTypeName]; ok { typeName, err = extString(extension) if err != nil { return outSchema, fmt.Errorf("invalid value for %q: %w", extGoTypeName, err) @@ -931,3 +948,18 @@ func setSkipOptionalPointerForContainerType(outSchema *Schema) { outSchema.SkipOptionalPointer = true } + +// combinedSchemaExtensions returns one set of extensions taking +// those from next to the $ref and the referenced schema itself. +// Extensions next to the $ref take precedence. +func combinedSchemaExtensions(r *openapi3.SchemaRef) map[string]any { + combined := map[string]any{} + + if r.Value != nil { + maps.Copy(combined, r.Value.Extensions) + } + + maps.Copy(combined, r.Extensions) + + return combined +} diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index fb921b58a2..df1593645b 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -1080,11 +1080,28 @@ func findSchemaNameByRefPath(refPath string, spec *openapi3.T) (string, error) { } func ParseGoImportExtension(v *openapi3.SchemaRef) (*goImport, error) { - if v.Value.Extensions[extPropGoImport] == nil || v.Value.Extensions[extPropGoType] == nil { + // An x-go-type-import is only meaningful in concert with an x-go-type + // override. Without one, the imported package is never referenced in + // the generated code, producing an "imported and not used" compile + // error. Require at least one x-go-type to be in scope (either next to + // the $ref or on the referenced schema) before collecting an import. + hasGoType := v.Extensions[extPropGoType] != nil || + (v.Value != nil && v.Value.Extensions[extPropGoType] != nil) + if !hasGoType { return nil, nil } - goTypeImportExt := v.Value.Extensions[extPropGoImport] + var goTypeImportExt any + + // check extensions next to the $ref before checking the schema itself + // values next to $ref will be used before those in the actual schema + if v.Extensions[extPropGoImport] != nil { + goTypeImportExt = v.Extensions[extPropGoImport] + } else if v.Value != nil && v.Value.Extensions[extPropGoImport] != nil { + goTypeImportExt = v.Value.Extensions[extPropGoImport] + } else { + return nil, nil + } importI, ok := goTypeImportExt.(map[string]any) if !ok { From f0626c2a7f6a6045b8f94f8918a583d9a18bd099 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 08:39:48 -0700 Subject: [PATCH 42/62] sanitize param names for http.ServeMux (#2279) * sanitize param names for http.ServeMux Go's net/http ServeMux requires wildcard segment names to be valid Go identifiers. OpenAPI specs can use path parameter names containing dashes (e.g. "addressing-identifier"), which causes a panic when registering routes with ServeMux. Fix by sanitizing parameter names in the stdhttp code path: - SwaggerUriToStdHttpUri now sanitizes param names via SanitizeGoIdentity so route patterns use valid Go identifiers (e.g. {addressing_identifier}) - stdhttp middleware template uses new SanitizedParamName for r.PathValue() calls to match the sanitized route pattern, while keeping the original ParamName for error messages - Add SanitizedParamName() method to ParameterDefinition for use by templates that need the sanitized form Add server-specific test directory with per-router integration tests exercising dashed path parameter names. Right now, only stdhttp has a test in this directory, but we'll do router specific tests in there in the future. Fixes #2278 Co-Authored-By: Claude Sonnet 4.6 * Regenerate boilerplate --------- Co-authored-by: Claude Sonnet 4.6 --- .../test/parameters/stdhttp/gen/server.gen.go | 4 +- internal/test/server-specific/spec.yaml | 24 +++ .../test/server-specific/stdhttp/config.yaml | 6 + internal/test/server-specific/stdhttp/doc.go | 3 + .../server-specific/stdhttp/server.gen.go | 180 ++++++++++++++++++ .../server-specific/stdhttp/server_test.go | 33 ++++ pkg/codegen/operations.go | 8 + .../stdhttp/std-http-middleware.tmpl | 6 +- pkg/codegen/utils.go | 28 ++- pkg/codegen/utils_test.go | 7 + 10 files changed, 287 insertions(+), 12 deletions(-) create mode 100644 internal/test/server-specific/spec.yaml create mode 100644 internal/test/server-specific/stdhttp/config.yaml create mode 100644 internal/test/server-specific/stdhttp/doc.go create mode 100644 internal/test/server-specific/stdhttp/server.gen.go create mode 100644 internal/test/server-specific/stdhttp/server_test.go diff --git a/internal/test/parameters/stdhttp/gen/server.gen.go b/internal/test/parameters/stdhttp/gen/server.gen.go index 520bb3ea46..06afd09a22 100644 --- a/internal/test/parameters/stdhttp/gen/server.gen.go +++ b/internal/test/parameters/stdhttp/gen/server.gen.go @@ -1214,7 +1214,7 @@ func (siw *ServerInterfaceWrapper) GetStartingWithNumber(w http.ResponseWriter, // ------------- Path parameter "1param" ------------- var n1param string - n1param = r.PathValue("1param") + n1param = r.PathValue("_param") handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { siw.Handler.GetStartingWithNumber(w, r, n1param) @@ -1373,7 +1373,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleNoExplodeArray/{param}", wrapper.GetSimpleNoExplodeArray) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simpleNoExplodeObject/{param}", wrapper.GetSimpleNoExplodeObject) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/simplePrimitive/{param}", wrapper.GetSimplePrimitive) - m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/startingWithNumber/{1param}", wrapper.GetStartingWithNumber) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/startingWithNumber/{_param}", wrapper.GetStartingWithNumber) return m } diff --git a/internal/test/server-specific/spec.yaml b/internal/test/server-specific/spec.yaml new file mode 100644 index 0000000000..ee8daefcdb --- /dev/null +++ b/internal/test/server-specific/spec.yaml @@ -0,0 +1,24 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Server-specific tests +paths: + # The dashed path parameter name "addressing-identifier" is not a valid Go + # identifier. This exercises GitHub issue #2278: stdhttp's ServeMux requires + # wildcard names to be valid Go identifiers. + /resources/{addressing-identifier}: + get: + operationId: getResource + parameters: + - name: addressing-identifier + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + content: + text/plain: + schema: + type: string diff --git a/internal/test/server-specific/stdhttp/config.yaml b/internal/test/server-specific/stdhttp/config.yaml new file mode 100644 index 0000000000..bcac4ff9be --- /dev/null +++ b/internal/test/server-specific/stdhttp/config.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: stdhttp +generate: + std-http-server: true + models: true +output: server.gen.go diff --git a/internal/test/server-specific/stdhttp/doc.go b/internal/test/server-specific/stdhttp/doc.go new file mode 100644 index 0000000000..17ae8b870d --- /dev/null +++ b/internal/test/server-specific/stdhttp/doc.go @@ -0,0 +1,3 @@ +package stdhttp + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml ../spec.yaml diff --git a/internal/test/server-specific/stdhttp/server.gen.go b/internal/test/server-specific/stdhttp/server.gen.go new file mode 100644 index 0000000000..16962d5dcc --- /dev/null +++ b/internal/test/server-specific/stdhttp/server.gen.go @@ -0,0 +1,180 @@ +//go:build go1.22 + +// Package stdhttp 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 stdhttp + +import ( + "fmt" + "net/http" + + "github.com/oapi-codegen/runtime" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /resources/{addressing-identifier}) + GetResource(w http.ResponseWriter, r *http.Request, addressingIdentifier string) +} + +// 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 + +// GetResource operation middleware +func (siw *ServerInterfaceWrapper) GetResource(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "addressing-identifier" ------------- + var addressingIdentifier string + + err = runtime.BindStyledParameterWithOptions("simple", "addressing-identifier", r.PathValue("addressing_identifier"), &addressingIdentifier, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "addressing-identifier", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetResource(w, r, addressingIdentifier) + })) + + 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.MethodGet+" "+options.BaseURL+"/resources/{addressing_identifier}", wrapper.GetResource) + + return m +} diff --git a/internal/test/server-specific/stdhttp/server_test.go b/internal/test/server-specific/stdhttp/server_test.go new file mode 100644 index 0000000000..8b06430952 --- /dev/null +++ b/internal/test/server-specific/stdhttp/server_test.go @@ -0,0 +1,33 @@ +//go:build go1.22 + +package stdhttp + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +type testServer struct { + receivedParam string +} + +func (s *testServer) GetResource(w http.ResponseWriter, r *http.Request, addressingIdentifier string) { + s.receivedParam = addressingIdentifier + _, _ = fmt.Fprint(w, addressingIdentifier) +} + +func TestDashedPathParam(t *testing.T) { + server := &testServer{} + handler := Handler(server) + + req := httptest.NewRequest(http.MethodGet, "/resources/my-value", nil) + rec := httptest.NewRecorder() + handler.ServeHTTP(rec, req) + + assert.Equal(t, http.StatusOK, rec.Code, "expected 200 OK, got %d; body: %s", rec.Code, rec.Body.String()) + assert.Equal(t, "my-value", server.receivedParam, "path parameter was not correctly extracted") +} diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index ec395284e7..ce0e98d2f0 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -153,6 +153,14 @@ func (pd *ParameterDefinition) SchemaFormat() string { return "" } +// SanitizedParamName returns the parameter name sanitized to be a valid Go +// identifier. This is needed for routers like net/http's ServeMux where path +// wildcards (e.g. {name}) must be valid Go identifiers. For the original +// OpenAPI parameter name (e.g. for error messages or JSON tags), use ParamName. +func (pd ParameterDefinition) SanitizedParamName() string { + return SanitizeGoIdentifier(pd.ParamName) +} + func (pd ParameterDefinition) GoVariableName() string { name := LowercaseFirstCharacters(pd.GoName()) if IsGoKeyword(name) { diff --git a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl index 00b0208555..8058ed1714 100644 --- a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl @@ -20,17 +20,17 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ var {{$varName := .GoVariableName}}{{$varName}} {{.TypeDef}} {{if .IsPassThrough}} - {{$varName}} = r.PathValue("{{.ParamName}}") + {{$varName}} = r.PathValue("{{.SanitizedParamName}}") {{end}} {{if .IsJson}} - err = json.Unmarshal([]byte(r.PathValue("{{.ParamName}}")), &{{$varName}}) + err = json.Unmarshal([]byte(r.PathValue("{{.SanitizedParamName}}")), &{{$varName}}) if err != nil { siw.ErrorHandlerFunc(w, r, &UnmarshalingParamError{ParamName: "{{.ParamName}}", Err: err}) return } {{end}} {{if .IsStyled}} - err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", r.PathValue("{{.ParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", r.PathValue("{{.SanitizedParamName}}"), &{{$varName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "{{.ParamName}}", Err: err}) return diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index df1593645b..bc1763ed5b 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -628,8 +628,9 @@ func SwaggerUriToGorillaUri(uri string) string { } // SwaggerUriToStdHttpUri converts a swagger style path URI with parameters to a -// Chi compatible path URI. We need to replace all Swagger parameters with -// "{param}". Valid input parameters are: +// net/http ServeMux compatible path URI. Parameter names are sanitized to be +// valid Go identifiers, as required by ServeMux wildcard segments. Valid input +// parameters are: // // {param} // {param*} @@ -646,7 +647,10 @@ func SwaggerUriToStdHttpUri(uri string) string { return "/{$}" } - return pathParamRE.ReplaceAllString(uri, "{$1}") + return pathParamRE.ReplaceAllStringFunc(uri, func(match string) string { + sub := pathParamRE.FindStringSubmatch(match) + return "{" + SanitizeGoIdentifier(sub[1]) + "}" + }) } // OrderedParamsFromUri returns the argument names, in order, in a given URI string, so for @@ -745,9 +749,12 @@ func IsValidGoIdentity(str string) bool { return !IsPredeclaredGoIdentifier(str) } -// SanitizeGoIdentity deletes and replaces the illegal runes in the given -// string to use the string as a valid identity. -func SanitizeGoIdentity(str string) string { +// SanitizeGoIdentifier replaces illegal runes in the given string so that +// it is a valid Go identifier. Unlike SanitizeGoIdentity, it does not +// prefix reserved keywords or predeclared identifiers. This is useful for +// contexts where the name must be a valid identifier but is not used as a +// Go symbol (e.g. net/http ServeMux wildcard names). +func SanitizeGoIdentifier(str string) string { sanitized := []rune(str) for i, c := range sanitized { @@ -758,7 +765,14 @@ func SanitizeGoIdentity(str string) string { } } - str = string(sanitized) + return string(sanitized) +} + +// SanitizeGoIdentity deletes and replaces the illegal runes in the given +// string to use the string as a valid identity. It also prefixes reserved +// keywords and predeclared identifiers with an underscore. +func SanitizeGoIdentity(str string) string { + str = SanitizeGoIdentifier(str) if IsGoKeyword(str) || IsPredeclaredGoIdentifier(str) { str = "_" + str diff --git a/pkg/codegen/utils_test.go b/pkg/codegen/utils_test.go index 3f9e0e8b76..9afe8b2d2e 100644 --- a/pkg/codegen/utils_test.go +++ b/pkg/codegen/utils_test.go @@ -454,6 +454,13 @@ func TestSwaggerUriToStdHttpUriUri(t *testing.T) { assert.Equal(t, "/path/{arg}/foo", SwaggerUriToStdHttpUri("/path/{;arg*}/foo")) assert.Equal(t, "/path/{arg}/foo", SwaggerUriToStdHttpUri("/path/{?arg}/foo")) assert.Equal(t, "/path/{arg}/foo", SwaggerUriToStdHttpUri("/path/{?arg*}/foo")) + + // Parameter names that are not valid Go identifiers must be sanitized (issue #2278) + assert.Equal(t, "/path/{addressing_identifier}", SwaggerUriToStdHttpUri("/path/{addressing-identifier}")) + assert.Equal(t, "/path/{my_param}/{other_param}", SwaggerUriToStdHttpUri("/path/{my-param}/{other-param}")) + + // Go keywords are valid ServeMux wildcard names and should not be prefixed + assert.Equal(t, "/path/{type}", SwaggerUriToStdHttpUri("/path/{type}")) } func TestOrderedParamsFromUri(t *testing.T) { From a10a2a22fdc5e01430d7da1684f5f58adfb9d4e6 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Sat, 28 Feb 2026 07:49:17 -0800 Subject: [PATCH 43/62] fix: support x-oapi-codegen-extra-tags on path params in strict-server RequestObject ParameterDefinition.JsonTag() only produced a `json:"..."` tag and ignored x-oapi-codegen-extra-tags. This meant path parameters in strict-server RequestObject structs never included extra struct tags, even though query/header/cookie parameters did (via GenerateParamsTypes). Update JsonTag() to read x-oapi-codegen-extra-tags from both the parameter and schema levels, with parameter-level taking precedence, matching the existing merge behavior in GenerateParamsTypes(). Fixes #2261 Co-Authored-By: Claude Opus 4.6 --- pkg/codegen/operations.go | 36 ++++++++++++++- pkg/codegen/operations_test.go | 82 ++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index ce0e98d2f0..b933d10289 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -66,12 +66,44 @@ func (pd ParameterDefinition) ZeroValueIsNil() bool { // JsonTag generates the JSON annotation to map GoType to json type name. If Parameter // Foo is marshaled to json as "foo", this will create the annotation // 'json:"foo"' +// It also includes any additional struct tags from x-oapi-codegen-extra-tags +// at the parameter or schema level (parameter-level takes precedence). func (pd *ParameterDefinition) JsonTag() string { + fieldTags := make(map[string]string) + if pd.Required { - return fmt.Sprintf("`json:\"%s\"`", pd.ParamName) + fieldTags["json"] = pd.ParamName } else { - return fmt.Sprintf("`json:\"%s,omitempty\"`", pd.ParamName) + fieldTags["json"] = pd.ParamName + ",omitempty" + } + + // Merge x-oapi-codegen-extra-tags from schema level first, then parameter level + // so that parameter-level takes precedence. + if pd.Spec != nil && pd.Spec.Schema != nil && pd.Spec.Schema.Value != nil { + if extension, ok := pd.Spec.Schema.Value.Extensions[extPropExtraTags]; ok { + if tags, err := extExtraTags(extension); err == nil { + for k, v := range tags { + fieldTags[k] = v + } + } + } + } + if pd.Spec != nil { + if extension, ok := pd.Spec.Extensions[extPropExtraTags]; ok { + if tags, err := extExtraTags(extension); err == nil { + for k, v := range tags { + fieldTags[k] = v + } + } + } + } + + keys := SortedMapKeys(fieldTags) + tags := make([]string, len(keys)) + for i, k := range keys { + tags[i] = fmt.Sprintf(`%s:"%s"`, k, fieldTags[k]) } + return "`" + strings.Join(tags, " ") + "`" } func (pd *ParameterDefinition) IsJson() bool { diff --git a/pkg/codegen/operations_test.go b/pkg/codegen/operations_test.go index 0eff03e2c2..fae988bbf6 100644 --- a/pkg/codegen/operations_test.go +++ b/pkg/codegen/operations_test.go @@ -18,6 +18,7 @@ import ( "testing" "github.com/getkin/kin-openapi/openapi3" + "github.com/stretchr/testify/assert" ) func TestIsJson(t *testing.T) { @@ -146,3 +147,84 @@ func TestGenerateDefaultOperationID(t *testing.T) { } } } + +func TestJsonTag(t *testing.T) { + t.Run("required param with no extra tags", func(t *testing.T) { + pd := ParameterDefinition{ + ParamName: "foo", + Required: true, + Spec: &openapi3.Parameter{}, + } + assert.Equal(t, "`json:\"foo\"`", pd.JsonTag()) + }) + + t.Run("optional param with no extra tags", func(t *testing.T) { + pd := ParameterDefinition{ + ParamName: "foo", + Required: false, + Spec: &openapi3.Parameter{}, + } + assert.Equal(t, "`json:\"foo,omitempty\"`", pd.JsonTag()) + }) + + t.Run("extra tags at parameter level", func(t *testing.T) { + pd := ParameterDefinition{ + ParamName: "foo", + Required: true, + Spec: &openapi3.Parameter{ + Extensions: map[string]any{ + "x-oapi-codegen-extra-tags": map[string]any{ + "validate": "required", + "db": "foo_col", + }, + }, + }, + } + assert.Equal(t, "`db:\"foo_col\" json:\"foo\" validate:\"required\"`", pd.JsonTag()) + }) + + t.Run("extra tags at schema level", func(t *testing.T) { + pd := ParameterDefinition{ + ParamName: "foo", + Required: true, + Spec: &openapi3.Parameter{ + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Extensions: map[string]any{ + "x-oapi-codegen-extra-tags": map[string]any{ + "validate": "required", + }, + }, + }, + }, + }, + } + assert.Equal(t, "`json:\"foo\" validate:\"required\"`", pd.JsonTag()) + }) + + t.Run("parameter level takes precedence over schema level", func(t *testing.T) { + pd := ParameterDefinition{ + ParamName: "foo", + Required: true, + Spec: &openapi3.Parameter{ + Extensions: map[string]any{ + "x-oapi-codegen-extra-tags": map[string]any{ + "validate": "param-level", + }, + }, + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Extensions: map[string]any{ + "x-oapi-codegen-extra-tags": map[string]any{ + "validate": "schema-level", + "db": "foo_col", + }, + }, + }, + }, + }, + } + // Parameter-level "validate" wins, schema-level "db" is kept + assert.Equal(t, "`db:\"foo_col\" json:\"foo\" validate:\"param-level\"`", pd.JsonTag()) + }) +} From 5b562c422adce153bc26ec31d05b5ae323dd4315 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Tue, 3 Mar 2026 11:53:25 -0800 Subject: [PATCH 44/62] Inline strict middleware typedefs Replace type aliases to runtime/strictmiddleware/* packages with inline type definitions in all strict server templates. This removes the unnecessary runtime dependency for StrictHandlerFunc and StrictMiddlewareFunc, and updates interface{} to any in the fiber template for consistency. Closes #2270 Co-Authored-By: Claude Opus 4.6 --- .../issues/issue-1093/api/child/child.gen.go | 5 ++--- .../issue-1093/api/parent/parent.gen.go | 5 ++--- .../test/issues/issue-1182/pkg1/pkg1.gen.go | 5 ++--- .../test/issues/issue-1182/pkg2/pkg2.gen.go | 5 ++--- .../issue-1208-1209/issue-multi-json.gen.go | 5 ++--- .../test/issues/issue-1212/pkg1/pkg1.gen.go | 5 ++--- .../test/issues/issue-1212/pkg2/pkg2.gen.go | 5 ++--- .../issues/issue-1277/content-array.gen.go | 5 ++--- .../test/issues/issue-1298/issue1298.gen.go | 5 ++--- .../issue-1378/bionicle/bionicle.gen.go | 5 ++--- .../issues/issue-1378/common/common.gen.go | 6 +++--- .../issue-1378/fooservice/fooservice.gen.go | 5 ++--- .../issue-1529/strict-echo/issue1529.gen.go | 5 ++--- .../issue-1529/strict-fiber/issue1529.gen.go | 3 +-- .../issue-1529/strict-iris/issue1529.gen.go | 5 ++--- internal/test/issues/issue-1676/ping.gen.go | 5 ++--- .../test/issues/issue-1963/issue1963.gen.go | 5 ++--- .../test/issues/issue-2113/gen/api/api.gen.go | 5 ++--- .../test/issues/issue-2190/issue2190.gen.go | 6 ++---- .../gen/spec_base/issue.gen.go | 5 ++--- .../gen/spec_ext/issue.gen.go | 6 +++--- internal/test/strict-server/chi/server.gen.go | 5 ++--- .../test/strict-server/echo/server.gen.go | 5 ++--- .../test/strict-server/fiber/server.gen.go | 3 +-- internal/test/strict-server/gin/server.gen.go | 5 ++--- .../test/strict-server/gorilla/server.gen.go | 5 ++--- .../test/strict-server/iris/server.gen.go | 5 ++--- .../test/strict-server/stdhttp/server.gen.go | 5 ++--- pkg/codegen/configuration.go | 21 ------------------- pkg/codegen/templates/strict/strict-echo.tmpl | 4 ++-- .../templates/strict/strict-echo5.tmpl | 4 ++-- .../templates/strict/strict-fiber.tmpl | 3 +-- pkg/codegen/templates/strict/strict-gin.tmpl | 4 ++-- pkg/codegen/templates/strict/strict-http.tmpl | 4 ++-- pkg/codegen/templates/strict/strict-iris.tmpl | 4 ++-- 35 files changed, 67 insertions(+), 116 deletions(-) diff --git a/internal/test/issues/issue-1093/api/child/child.gen.go b/internal/test/issues/issue-1093/api/child/child.gen.go index 3716a0ba9c..d50664c315 100644 --- a/internal/test/issues/issue-1093/api/child/child.gen.go +++ b/internal/test/issues/issue-1093/api/child/child.gen.go @@ -18,7 +18,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1093/api/parent" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // ServerInterface represents all server handlers. @@ -108,8 +107,8 @@ type StrictServerInterface interface { GetPets(ctx context.Context, request GetPetsRequestObject) (GetPetsResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1093/api/parent/parent.gen.go b/internal/test/issues/issue-1093/api/parent/parent.gen.go index 0aada7045e..6f6f7d869b 100644 --- a/internal/test/issues/issue-1093/api/parent/parent.gen.go +++ b/internal/test/issues/issue-1093/api/parent/parent.gen.go @@ -17,7 +17,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // Pet defines model for Pet. @@ -113,8 +112,8 @@ type StrictServerInterface interface { GetPets(ctx context.Context, request GetPetsRequestObject) (GetPetsResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go index c5111c09d2..5baac42d25 100644 --- a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go @@ -18,7 +18,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/labstack/echo/v4" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1182/pkg2" - strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" ) // RequestEditorFn is the function signature for the RequestEditor callback function @@ -312,8 +311,8 @@ type StrictServerInterface interface { TestGet(ctx context.Context, request TestGetRequestObject) (TestGetResponseObject, error) } -type StrictHandlerFunc = strictecho.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go index 51eece40aa..df4e45e12d 100644 --- a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go @@ -16,7 +16,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/labstack/echo/v4" - strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" ) // RequestEditorFn is the function signature for the RequestEditor callback function @@ -181,8 +180,8 @@ type ResponseWithReferenceResponse struct { type StrictServerInterface interface { } -type StrictHandlerFunc = strictecho.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index a5f1602504..72270f9356 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -18,7 +18,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // Bar defines model for bar. @@ -425,8 +424,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index 025f02314c..2b4d87954a 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -20,7 +20,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1212/pkg2" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // RequestEditorFn is the function signature for the RequestEditor callback function @@ -325,8 +324,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go index d4c338cce7..1aeee27bac 100644 --- a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go @@ -17,7 +17,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // Bar defines model for bar. @@ -186,8 +185,8 @@ type TestMultipartResponse func(writer *multipart.Writer) error type StrictServerInterface interface { } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1277/content-array.gen.go b/internal/test/issues/issue-1277/content-array.gen.go index be4983aa29..8a0c29b2e3 100644 --- a/internal/test/issues/issue-1277/content-array.gen.go +++ b/internal/test/issues/issue-1277/content-array.gen.go @@ -14,7 +14,6 @@ import ( "strings" "github.com/go-chi/chi/v5" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // RequestEditorFn is the function signature for the RequestEditor callback function @@ -443,8 +442,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-1298/issue1298.gen.go b/internal/test/issues/issue-1298/issue1298.gen.go index 9d156149f6..3d79747d26 100644 --- a/internal/test/issues/issue-1298/issue1298.gen.go +++ b/internal/test/issues/issue-1298/issue1298.gen.go @@ -15,7 +15,6 @@ import ( "strings" "github.com/gin-gonic/gin" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // Test defines model for Test. @@ -363,8 +362,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index ad3c48fb16..f708015ae6 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -19,7 +19,6 @@ import ( "github.com/gorilla/mux" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1378/common" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // Bionicle defines model for Bionicle. @@ -235,8 +234,8 @@ type StrictServerInterface interface { GetBionicleName(ctx context.Context, request GetBionicleNameRequestObject) (GetBionicleNameResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-1378/common/common.gen.go b/internal/test/issues/issue-1378/common/common.gen.go index d1747783e0..0e725531e7 100644 --- a/internal/test/issues/issue-1378/common/common.gen.go +++ b/internal/test/issues/issue-1378/common/common.gen.go @@ -6,6 +6,7 @@ package common import ( "bytes" "compress/gzip" + "context" "encoding/base64" "fmt" "net/http" @@ -15,7 +16,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gorilla/mux" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ErrTracingIdNotSent defines model for ErrTracingIdNotSent. @@ -151,8 +151,8 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H type StrictServerInterface interface { } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index cf32c3e258..9c856f981b 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -20,7 +20,6 @@ import ( externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1378/bionicle" externalRef1 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1378/common" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -228,8 +227,8 @@ type StrictServerInterface interface { GetBionicleName(ctx context.Context, request GetBionicleNameRequestObject) (GetBionicleNameResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index 04180c2821..5356f847bb 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -18,7 +18,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/labstack/echo/v4" - strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" ) // Test defines model for Test. @@ -377,8 +376,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictecho.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index 8b1ceac003..4ead2d3d10 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -369,8 +369,7 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc func(ctx *fiber.Ctx, args interface{}) (interface{}, error) - +type StrictHandlerFunc func(ctx *fiber.Ctx, args any) (any, error) type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { diff --git a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go index e2a01bd04a..0a990102f2 100644 --- a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go @@ -18,7 +18,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/kataras/iris/v12" - strictiris "github.com/oapi-codegen/runtime/strictmiddleware/iris" ) // Test defines model for Test. @@ -353,8 +352,8 @@ type StrictServerInterface interface { Test(ctx context.Context, request TestRequestObject) (TestResponseObject, error) } -type StrictHandlerFunc = strictiris.StrictIrisHandlerFunc -type StrictMiddlewareFunc = strictiris.StrictIrisMiddlewareFunc +type StrictHandlerFunc func(ctx iris.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/issues/issue-1676/ping.gen.go b/internal/test/issues/issue-1676/ping.gen.go index 395033a2ba..30229f8183 100644 --- a/internal/test/issues/issue-1676/ping.gen.go +++ b/internal/test/issues/issue-1676/ping.gen.go @@ -9,7 +9,6 @@ import ( "net/http" "github.com/gorilla/mux" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -195,8 +194,8 @@ type StrictServerInterface interface { GetPing(ctx context.Context, request GetPingRequestObject) (GetPingResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-1963/issue1963.gen.go b/internal/test/issues/issue-1963/issue1963.gen.go index 15164e4b62..b2968de7b7 100644 --- a/internal/test/issues/issue-1963/issue1963.gen.go +++ b/internal/test/issues/issue-1963/issue1963.gen.go @@ -15,7 +15,6 @@ import ( "net/http" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // Request defines model for Request. @@ -405,8 +404,8 @@ type StrictServerInterface interface { TextEndpoint(ctx context.Context, request TextEndpointRequestObject) (TextEndpointResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-2113/gen/api/api.gen.go b/internal/test/issues/issue-2113/gen/api/api.gen.go index 626e5ea1f6..9aa3018f10 100644 --- a/internal/test/issues/issue-2113/gen/api/api.gen.go +++ b/internal/test/issues/issue-2113/gen/api/api.gen.go @@ -12,7 +12,6 @@ import ( "github.com/go-chi/chi/v5" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2113/gen/common" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -233,8 +232,8 @@ type StrictServerInterface interface { ListThings(ctx context.Context, request ListThingsRequestObject) (ListThingsResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-2190/issue2190.gen.go b/internal/test/issues/issue-2190/issue2190.gen.go index 0904608db2..db31e6c1c3 100644 --- a/internal/test/issues/issue-2190/issue2190.gen.go +++ b/internal/test/issues/issue-2190/issue2190.gen.go @@ -14,8 +14,6 @@ import ( "net/http" "net/url" "strings" - - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // Success defines model for Success. @@ -447,8 +445,8 @@ type StrictServerInterface interface { GetTest(ctx context.Context, request GetTestRequestObject) (GetTestResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go index f96b78c9b2..57ad01efb4 100644 --- a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go @@ -12,7 +12,6 @@ import ( "github.com/go-chi/chi/v5" externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-removed-external-ref/gen/spec_ext" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // DirectBar defines model for DirectBar. @@ -266,8 +265,8 @@ type StrictServerInterface interface { PostNoTrouble(ctx context.Context, request PostNoTroubleRequestObject) (PostNoTroubleResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go index 881f8be12b..b7809cd969 100644 --- a/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go @@ -4,11 +4,11 @@ package spec_ext import ( + "context" "fmt" "net/http" "github.com/go-chi/chi/v5" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // CamelSchema defines model for CamelSchema. @@ -165,8 +165,8 @@ type PascalJSONResponse PascalSchema type StrictServerInterface interface { } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index a86b27c501..e5a9ebb9d0 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -22,7 +22,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/go-chi/chi/v5" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -1269,8 +1268,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 88036c38f4..414667b5b5 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -22,7 +22,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/labstack/echo/v4" "github.com/oapi-codegen/runtime" - strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" ) // ServerInterface represents all server handlers. @@ -989,8 +988,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictecho.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index 37615230b7..bdb00bfcdb 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -1087,8 +1087,7 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc func(ctx *fiber.Ctx, args interface{}) (interface{}, error) - +type StrictHandlerFunc func(ctx *fiber.Ctx, args any) (any, error) type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 44d017dbd8..0e5e4bd7f1 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -22,7 +22,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gin-gonic/gin" "github.com/oapi-codegen/runtime" - strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" ) // ServerInterface represents all server handlers. @@ -1064,8 +1063,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 13c5969597..9b3f8315ea 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -22,7 +22,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/gorilla/mux" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -1180,8 +1179,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 7ae7eb409b..66d0dce0bb 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -22,7 +22,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/kataras/iris/v12" "github.com/oapi-codegen/runtime" - strictiris "github.com/oapi-codegen/runtime/strictmiddleware/iris" ) // ServerInterface represents all server handlers. @@ -922,8 +921,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictiris.StrictIrisHandlerFunc -type StrictMiddlewareFunc = strictiris.StrictIrisMiddlewareFunc +type StrictHandlerFunc func(ctx iris.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 2034ce7be7..74e78af517 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -23,7 +23,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -1175,8 +1174,8 @@ type StrictServerInterface interface { UnionExample(ctx context.Context, request UnionExampleRequestObject) (UnionExampleResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go index 7938aa9fdb..f0a549a897 100644 --- a/pkg/codegen/configuration.go +++ b/pkg/codegen/configuration.go @@ -153,41 +153,20 @@ func (g GenerateOptions) RouterImports() []AdditionalImport { switch { case g.EchoServer: imports = append(imports, AdditionalImport{Package: "github.com/labstack/echo/v4"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictecho", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo"}) - } case g.Echo5Server: imports = append(imports, AdditionalImport{Package: "github.com/labstack/echo/v5"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictecho5", Package: "github.com/oapi-codegen/runtime/strictmiddleware/echo-v5"}) - } case g.ChiServer: imports = append(imports, AdditionalImport{Package: "github.com/go-chi/chi/v5"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) - } case g.GinServer: imports = append(imports, AdditionalImport{Package: "github.com/gin-gonic/gin"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictgin", Package: "github.com/oapi-codegen/runtime/strictmiddleware/gin"}) - } case g.GorillaServer: imports = append(imports, AdditionalImport{Package: "github.com/gorilla/mux"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) - } case g.FiberServer: imports = append(imports, AdditionalImport{Package: "github.com/gofiber/fiber/v2"}) case g.IrisServer: imports = append(imports, AdditionalImport{Package: "github.com/kataras/iris/v12"}) imports = append(imports, AdditionalImport{Package: "github.com/kataras/iris/v12/core/router"}) - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictiris", Package: "github.com/oapi-codegen/runtime/strictmiddleware/iris"}) - } case g.StdHTTPServer: - if g.Strict { - imports = append(imports, AdditionalImport{Alias: "strictnethttp", Package: "github.com/oapi-codegen/runtime/strictmiddleware/nethttp"}) - } } return imports diff --git a/pkg/codegen/templates/strict/strict-echo.tmpl b/pkg/codegen/templates/strict/strict-echo.tmpl index f8b523fa91..7981c76b9e 100644 --- a/pkg/codegen/templates/strict/strict-echo.tmpl +++ b/pkg/codegen/templates/strict/strict-echo.tmpl @@ -1,5 +1,5 @@ -type StrictHandlerFunc = strictecho.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/pkg/codegen/templates/strict/strict-echo5.tmpl b/pkg/codegen/templates/strict/strict-echo5.tmpl index 1073714599..a7e617c1ae 100644 --- a/pkg/codegen/templates/strict/strict-echo5.tmpl +++ b/pkg/codegen/templates/strict/strict-echo5.tmpl @@ -1,5 +1,5 @@ -type StrictHandlerFunc = strictecho5.StrictEchoHandlerFunc -type StrictMiddlewareFunc = strictecho5.StrictEchoMiddlewareFunc +type StrictHandlerFunc func(ctx *echo.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} diff --git a/pkg/codegen/templates/strict/strict-fiber.tmpl b/pkg/codegen/templates/strict/strict-fiber.tmpl index 106f33a766..786a11aef8 100644 --- a/pkg/codegen/templates/strict/strict-fiber.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber.tmpl @@ -1,5 +1,4 @@ -type StrictHandlerFunc func(ctx *fiber.Ctx, args interface{}) (interface{}, error) - +type StrictHandlerFunc func(ctx *fiber.Ctx, args any) (any, error) type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { diff --git a/pkg/codegen/templates/strict/strict-gin.tmpl b/pkg/codegen/templates/strict/strict-gin.tmpl index 893e4b4046..167bff762e 100644 --- a/pkg/codegen/templates/strict/strict-gin.tmpl +++ b/pkg/codegen/templates/strict/strict-gin.tmpl @@ -1,5 +1,5 @@ -type StrictHandlerFunc = strictgin.StrictGinHandlerFunc -type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc +type StrictHandlerFunc func(ctx *gin.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc type StrictGinServerOptions struct { // RequestErrorHandlerFunc is called when a request cannot be parsed or diff --git a/pkg/codegen/templates/strict/strict-http.tmpl b/pkg/codegen/templates/strict/strict-http.tmpl index d55341ca0b..16a902456c 100644 --- a/pkg/codegen/templates/strict/strict-http.tmpl +++ b/pkg/codegen/templates/strict/strict-http.tmpl @@ -1,5 +1,5 @@ -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/pkg/codegen/templates/strict/strict-iris.tmpl b/pkg/codegen/templates/strict/strict-iris.tmpl index 804efb0cf3..f6342ee37a 100644 --- a/pkg/codegen/templates/strict/strict-iris.tmpl +++ b/pkg/codegen/templates/strict/strict-iris.tmpl @@ -1,5 +1,5 @@ -type StrictHandlerFunc = strictiris.StrictIrisHandlerFunc -type StrictMiddlewareFunc = strictiris.StrictIrisMiddlewareFunc +type StrictHandlerFunc func(ctx iris.Context, request any) (any, error) +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { return &strictHandler{ssi: ssi, middlewares: middlewares} From 6ac5bddaaa6c2a989f6ea903eff813161c66583a Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 09:14:37 -0700 Subject: [PATCH 45/62] Update Greptile settings All code review is now automatic, and I gave Greptile a set of code review suggestions, which we will update as we learn to use it better. --- .greptile/config.json | 5 ++++ .greptile/rules.md | 66 +++++++++++++++++++++++++++++++++++++++++++ greptile.json | 4 --- 3 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 .greptile/config.json create mode 100644 .greptile/rules.md delete mode 100644 greptile.json diff --git a/.greptile/config.json b/.greptile/config.json new file mode 100644 index 0000000000..5fe0cdf421 --- /dev/null +++ b/.greptile/config.json @@ -0,0 +1,5 @@ +{ + "strictness": 2, + "commentTypes": ["logic", "syntax"] +} + diff --git a/.greptile/rules.md b/.greptile/rules.md new file mode 100644 index 0000000000..4384b267c7 --- /dev/null +++ b/.greptile/rules.md @@ -0,0 +1,66 @@ +# Code Review Rules for oapi-codegen + +These rules guide automated code review for this repository. oapi-codegen is a code generator that turns OpenAPI 3.x specs into Go server stubs, clients, and types. The primary risk surface in any change is **the generated output that downstream users compile against** — review with that in mind. + +## 1. Generated files (`*.gen.go`) + +Files matching `*.gen.go` are produced by the code generator and committed to source control so CI can verify they are up-to-date. You do **not** need to read every generated file in a PR — spot check a representative sample. + +When spot checking, look for: + +- **Drift unrelated to the stated change.** If the PR claims to fix X, but a `*.gen.go` diff also shows unrelated reshuffling (renamed identifiers, reordered methods, formatting churn, removed comments, regenerated imports), call it out. This often indicates an accidental commit from a different branch, an out-of-date local toolchain, or a template change the author did not intend. +- **Diffs that look "too small" for the described change.** If the PR claims to add a new code generation feature but the only generated diff is a one-line tweak in one file, the test fixtures may not have been regenerated — flag it. +- **Diffs that look "too large" for the described change.** A small template tweak should not produce thousands of lines of churn across every fixture. If it does, the template change probably has a wider blast radius than the author realized. + +You do not need to suggest stylistic improvements inside `*.gen.go` files — they are templated output, not hand-written code. + +## 2. Configuration changes must update the JSON schema + +Whenever `pkg/codegen/configuration.go` is modified — particularly the `Configuration`, `GenerateOptions`, `OutputOptions`, or `CompatibilityOptions` structs — the corresponding JSON Schema at `configuration-schema.json` (repo root) **must** be updated to match. + +Flag any PR that changes `pkg/codegen/configuration.go` without a corresponding edit to `configuration-schema.json`. The schema is consumed by IDEs and validation tooling; an out-of-sync schema silently breaks downstream users' configs. + +## 3. Watch for breaking changes to the generated API surface + +Generated code is compiled into downstream users' binaries. Any change that alters the **shape** of generated code is a potential breaking change for every user of oapi-codegen, even if the change is "just" in a template. + +Flag the following patterns and call them out as breaking-change risks: + +- **Function/method signature changes** in generated server interfaces, client methods, or strict server handler types — added/removed/reordered parameters, changed return types, changed receiver types. +- **Removed or renamed exported types, functions, methods, fields, or constants** in generated output. +- **Changed Go types for existing fields** (e.g., `*string` → `string`, `int` → `int64`, switching between value and pointer receivers, swapping a concrete type for an interface). +- **Renamed JSON struct tags** or other tags that affect serialization wire format. +- **Reordered struct fields** when the struct is embedded or used in positional contexts (rare but worth noting). +- **Removed or renamed template helper functions** that user-supplied template overrides may depend on (templates in `pkg/codegen/templates/` and helpers in `pkg/codegen/template_helpers.go`). + +Per the project's stated practice, behavior-changing features in codegen should be **opt-in via configuration** (new flags under `generate`, `output-options`, or `compatibility`), not silent breaking changes. If you see a behavior change that is unconditional, ask whether it should be gated behind a new compatibility flag. + +## 4. Template changes should be evaluated across all router backends + +The repo supports multiple server frameworks via separate template subdirectories under `pkg/codegen/templates/`: + +- `chi/` +- `echo/` +- `fiber/` +- `gin/` +- `gorilla/` +- `iris/` +- `stdhttp/` (net/http ServeMux, Go 1.22+) +- `strict/` (the strict-server wrapper layer, applied on top of any backend) + +Plus shared templates at the top level: `client.tmpl`, `client-with-responses.tmpl`, `typedef.tmpl`, `param-types.tmpl`, `request-bodies.tmpl`, `inline.tmpl`, `imports.tmpl`, `constants.tmpl`, `server-urls.tmpl`, `additional-properties.tmpl`, `union.tmpl`, `union-and-additional-properties.tmpl`. + +When a PR modifies a template, ask: + +- **Does this change apply to other backends?** A bug fix or new feature in one backend's template often needs an analogous fix in the others. The implementation will not be identical — each framework has its own routing, middleware, and parameter-binding idioms — but the *intent* should usually be applied everywhere it is relevant. +- **If only one backend is touched, is that intentional?** A change scoped to a single backend may be correct (e.g., a Fiber-specific bug, a Gin-specific middleware quirk). If so, the PR description should explain why. If there is no such explanation and the change looks generally applicable, flag it. +- **Did the strict-server templates need a corresponding update?** Strict-mode wraps the per-backend handlers and frequently needs parallel changes. +- **Were the integration tests in `internal/test/` updated?** This module imports every framework and is the primary place backend-parity bugs surface. + +Be pragmatic: do not demand identical changes in seven places. Do your best to assess whether a change is conceptually backend-agnostic (most template changes are) or genuinely backend-specific (some are), and flag missing parity only when the change looks generally applicable. + +## 5. General + +- The repo is a multi-module monorepo. Cross-module changes (e.g., to `runtime/` consumers) deserve extra scrutiny. +- `internal/test/` contains regression tests keyed to GitHub issues. New bug fixes should generally include a regression test there. +- Generated files are committed; CI fails if `make generate` produces a diff. If a PR's generated files look stale, that will fail CI regardless — but flagging it in review saves a round-trip. diff --git a/greptile.json b/greptile.json deleted file mode 100644 index bc3cc79fc0..0000000000 --- a/greptile.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "skipReview": "AUTOMATIC", - "ignorePatterns": "**/*.gen.go" -} From 2620715239c67a28b41e6fc6a204c63c72aefeda Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 09:27:54 -0700 Subject: [PATCH 46/62] Update .greptile/config.json Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- .greptile/config.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.greptile/config.json b/.greptile/config.json index 5fe0cdf421..e301f7f66f 100644 --- a/.greptile/config.json +++ b/.greptile/config.json @@ -1,5 +1,13 @@ +{ { "strictness": 2, - "commentTypes": ["logic", "syntax"] + "commentTypes": ["logic", "syntax"], + "fileSettings": [ + { + "pattern": "**/*.gen.go", + "strictness": 1, + "commentTypes": ["logic"] + } + ] } From 44f8bb62abd4cf0ff15f3622580ce14003ff8820 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Tue, 21 Apr 2026 09:09:03 -0700 Subject: [PATCH 47/62] fix: pointer skipping for client query params Closes: #2329 Parameter-level x-go-type-skip-optional-pointer: true on a map- or slice-typed query parameter produced a struct field without a pointer (correct) but a client builder that still dereferenced it (*params.Field), so the generated package failed to compile. The params-struct path in GenStructFromSchema already read the parameter-level extension; DescribeParameters did not, leaving Schema.SkipOptionalPointer false on the ParameterDefinition that backs the client template. Mirror the override there. Also extend ZeroValueIsNil to recognize map[K]V so the emitted nil-check is not dropped when the optional pointer is skipped. Adds a regression fixture under internal/test/issues/issue-2329 covering both the deepObject map and form-style slice cases. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/test/issues/issue-2329/config.yaml | 5 + internal/test/issues/issue-2329/generate.go | 3 + .../test/issues/issue-2329/issue2329.gen.go | 269 ++++++++++++++++++ .../test/issues/issue-2329/issue2329_test.go | 47 +++ internal/test/issues/issue-2329/openapi.yaml | 27 ++ pkg/codegen/operations.go | 25 +- 6 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 internal/test/issues/issue-2329/config.yaml create mode 100644 internal/test/issues/issue-2329/generate.go create mode 100644 internal/test/issues/issue-2329/issue2329.gen.go create mode 100644 internal/test/issues/issue-2329/issue2329_test.go create mode 100644 internal/test/issues/issue-2329/openapi.yaml diff --git a/internal/test/issues/issue-2329/config.yaml b/internal/test/issues/issue-2329/config.yaml new file mode 100644 index 0000000000..8ec05d874a --- /dev/null +++ b/internal/test/issues/issue-2329/config.yaml @@ -0,0 +1,5 @@ +package: issue2329 +generate: + models: true + client: true +output: issue2329.gen.go diff --git a/internal/test/issues/issue-2329/generate.go b/internal/test/issues/issue-2329/generate.go new file mode 100644 index 0000000000..0b97157539 --- /dev/null +++ b/internal/test/issues/issue-2329/generate.go @@ -0,0 +1,3 @@ +package issue2329 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml openapi.yaml diff --git a/internal/test/issues/issue-2329/issue2329.gen.go b/internal/test/issues/issue-2329/issue2329.gen.go new file mode 100644 index 0000000000..c16222c930 --- /dev/null +++ b/internal/test/issues/issue-2329/issue2329.gen.go @@ -0,0 +1,269 @@ +// Package issue2329 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 issue2329 + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// ListThingsParams defines parameters for ListThings. +type ListThingsParams struct { + Tags map[string]string `json:"tags,omitempty"` + Labels []string `form:"labels,omitempty" json:"labels,omitempty"` +} + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // ListThings request + ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListThingsRequest(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) +} + +// NewListThingsRequest generates requests for ListThings +func NewListThingsRequest(server string, params *ListThingsParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/things") + 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.Tags != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("deepObject", true, "tags", params.Tags, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "object", Format: ""}); err != nil { + return nil, err + } else { + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } + } + + } + + if params.Labels != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "labels", params.Labels, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", 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 +} + +func (c *Client) 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 *Client) 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 { + // ListThingsWithResponse request + ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) +} + +type ListThingsResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r ListThingsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListThingsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// ListThingsWithResponse request returning *ListThingsResponse +func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { + rsp, err := c.ListThings(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseListThingsResponse(rsp) +} + +// ParseListThingsResponse parses an HTTP response from a ListThingsWithResponse call +func ParseListThingsResponse(rsp *http.Response) (*ListThingsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListThingsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/issues/issue-2329/issue2329_test.go b/internal/test/issues/issue-2329/issue2329_test.go new file mode 100644 index 0000000000..b7456f6a5e --- /dev/null +++ b/internal/test/issues/issue-2329/issue2329_test.go @@ -0,0 +1,47 @@ +package issue2329 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestNewListThingsRequest verifies that map- and slice-typed optional query +// parameters marked with `x-go-type-skip-optional-pointer: true` produce +// client request code that compiles. Before the fix, the client template +// emitted `*params.Tags` / `*params.Labels`, which does not compile because +// the fields are declared as `map[string]string` and `[]string`. +func TestNewListThingsRequest(t *testing.T) { + t.Run("nil map and slice query params are not sent", func(t *testing.T) { + params := ListThingsParams{} + + req, err := NewListThingsRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.Empty(t, req.URL.RawQuery) + }) + + t.Run("non-nil map query param (deepObject) is serialized", func(t *testing.T) { + params := ListThingsParams{ + Tags: map[string]string{"color": "blue"}, + } + + req, err := NewListThingsRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.Contains(t, req.URL.RawQuery, "tags[color]=blue") + }) + + t.Run("non-nil slice query param (form, explode) is serialized", func(t *testing.T) { + params := ListThingsParams{ + Labels: []string{"a", "b"}, + } + + req, err := NewListThingsRequest("https://localhost", ¶ms) + require.NoError(t, err) + + assert.Contains(t, req.URL.RawQuery, "labels=a") + assert.Contains(t, req.URL.RawQuery, "labels=b") + }) +} diff --git a/internal/test/issues/issue-2329/openapi.yaml b/internal/test/issues/issue-2329/openapi.yaml new file mode 100644 index 0000000000..692bc8b1a7 --- /dev/null +++ b/internal/test/issues/issue-2329/openapi.yaml @@ -0,0 +1,27 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Issue 2329 +paths: + /things: + get: + operationId: listThings + parameters: + - name: tags + in: query + style: deepObject + x-go-type-skip-optional-pointer: true + schema: + type: object + additionalProperties: + type: string + - name: labels + in: query + x-go-type-skip-optional-pointer: true + schema: + type: array + items: + type: string + responses: + "200": + description: OK diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index b933d10289..4933e35964 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -52,15 +52,21 @@ func (pd ParameterDefinition) RequiresNilCheck() bool { return pd.ZeroValueIsNil() || pd.HasOptionalPointer() } -// ZeroValueIsNil is a helper function to determine if the given Go type used for this property -// Will return true if the OpenAPI `type` is: -// - `array` +// ZeroValueIsNil is a helper function to determine if the given Go type used +// for this property has `nil` as its Go zero value. Slices (OpenAPI `array`) +// and maps (OpenAPI `object` with only `additionalProperties`, rendered as +// `map[K]V`) both satisfy this — templates use it to decide whether to emit a +// nil-check before reading the field. func (pd ParameterDefinition) ZeroValueIsNil() bool { if pd.Schema.OAPISchema == nil { return false } - return pd.Schema.OAPISchema.Type.Is("array") + if pd.Schema.OAPISchema.Type.Is("array") { + return true + } + + return strings.HasPrefix(pd.Schema.GoType, "map[") } // JsonTag generates the JSON annotation to map GoType to json type name. If Parameter @@ -258,6 +264,17 @@ func DescribeParameters(params openapi3.Parameters, path []string) ([]ParameterD Schema: goType, } + // A parameter-level `x-go-type-skip-optional-pointer` overrides the + // schema-level setting. `GenStructFromSchema` applies the same override + // when rendering the params struct; without mirroring it here, the + // client/server templates disagree with the struct definition and emit + // a dereference (`*params.Field`) on a field declared without a pointer. + if extension, ok := param.Extensions[extPropGoTypeSkipOptionalPointer]; ok { + if skipOptionalPointer, err := extParsePropGoTypeSkipOptionalPointer(extension); err == nil { + pd.Schema.SkipOptionalPointer = skipOptionalPointer + } + } + // If this is a reference to a predefined type, simply use the reference // name as the type. $ref: "#/components/schemas/custom_type" becomes // "CustomType". From 5e2edce5b6bbdc08b803487e61b395ea5acb7320 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 09:34:02 -0700 Subject: [PATCH 48/62] Regenerate boilerplate --- internal/test/issues/issue-2329/issue2329.gen.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/test/issues/issue-2329/issue2329.gen.go b/internal/test/issues/issue-2329/issue2329.gen.go index c16222c930..22692c0969 100644 --- a/internal/test/issues/issue-2329/issue2329.gen.go +++ b/internal/test/issues/issue-2329/issue2329.gen.go @@ -243,6 +243,14 @@ func (r ListThingsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ListThingsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ListThingsWithResponse request returning *ListThingsResponse func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { rsp, err := c.ListThings(ctx, params, reqEditors...) From e8a39e18a21d2989add5ed66541e9a105dd8440a Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 09:42:22 -0700 Subject: [PATCH 49/62] fix: pointer skipping for body schema map properties Property.ZeroValueIsNil mirrored ParameterDefinition.ZeroValueIsNil only for arrays. A map-typed property on a body schema with a custom MarshalJSON (i.e. one with additionalProperties or in oneOf/anyOf) and x-go-type-skip-optional-pointer: true emitted no nil-check, so an unset map field serialised as `"field":null` while an unset slice field with the same flag was omitted. Mirror the map-prefix check from operations.go so both kinds of zero value are treated consistently in the additional-properties / union / union-and-additional-properties templates. Extends the issue-2329 fixture with a Thing body schema covering both map and slice properties; the regression test marshals a zero-value Thing and asserts neither field appears in the JSON object. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/test/components/components.gen.go | 8 +- .../test/issues/issue-2329/issue2329.gen.go | 231 ++++++++++++++++++ .../test/issues/issue-2329/issue2329_test.go | 33 +++ internal/test/issues/issue-2329/openapi.yaml | 27 ++ pkg/codegen/schema.go | 14 +- pkg/codegen/schema_test.go | 8 + 6 files changed, 314 insertions(+), 7 deletions(-) diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go index 0bfc1747e6..e8550c87b3 100644 --- a/internal/test/components/components.gen.go +++ b/internal/test/components/components.gen.go @@ -647,9 +647,11 @@ func (a BodyWithAddPropsJSONBody) MarshalJSON() ([]byte, error) { var err error object := make(map[string]json.RawMessage) - object["inner"], err = json.Marshal(a.Inner) - if err != nil { - return nil, fmt.Errorf("error marshaling 'inner': %w", err) + if a.Inner != nil { + object["inner"], err = json.Marshal(a.Inner) + if err != nil { + return nil, fmt.Errorf("error marshaling 'inner': %w", err) + } } object["name"], err = json.Marshal(a.Name) diff --git a/internal/test/issues/issue-2329/issue2329.gen.go b/internal/test/issues/issue-2329/issue2329.gen.go index 22692c0969..06e9baa719 100644 --- a/internal/test/issues/issue-2329/issue2329.gen.go +++ b/internal/test/issues/issue-2329/issue2329.gen.go @@ -4,7 +4,9 @@ package issue2329 import ( + "bytes" "context" + "encoding/json" "fmt" "io" "net/http" @@ -14,12 +16,105 @@ import ( "github.com/oapi-codegen/runtime" ) +// Thing defines model for Thing. +type Thing struct { + Labels []string `json:"labels,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + AdditionalProperties map[string]string `json:"-"` +} + // ListThingsParams defines parameters for ListThings. type ListThingsParams struct { Tags map[string]string `json:"tags,omitempty"` Labels []string `form:"labels,omitempty" json:"labels,omitempty"` } +// CreateThingJSONRequestBody defines body for CreateThing for application/json ContentType. +type CreateThingJSONRequestBody = Thing + +// Getter for additional properties for Thing. Returns the specified +// element and whether it was found +func (a Thing) Get(fieldName string) (value string, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for Thing +func (a *Thing) Set(fieldName string, value string) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]string) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for Thing to handle AdditionalProperties +func (a *Thing) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["labels"]; found { + err = json.Unmarshal(raw, &a.Labels) + if err != nil { + return fmt.Errorf("error reading 'labels': %w", err) + } + delete(object, "labels") + } + + if raw, found := object["tags"]; found { + err = json.Unmarshal(raw, &a.Tags) + if err != nil { + return fmt.Errorf("error reading 'tags': %w", err) + } + delete(object, "tags") + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]string) + for fieldName, fieldBuf := range object { + var fieldVal string + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for Thing to handle AdditionalProperties +func (a Thing) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + if a.Labels != nil { + object["labels"], err = json.Marshal(a.Labels) + if err != nil { + return nil, fmt.Errorf("error marshaling 'labels': %w", err) + } + } + + if a.Tags != nil { + object["tags"], err = json.Marshal(a.Tags) + if err != nil { + return nil, fmt.Errorf("error marshaling 'tags': %w", err) + } + } + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -95,6 +190,11 @@ func WithRequestEditorFn(fn RequestEditorFn) ClientOption { type ClientInterface interface { // ListThings request ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateThingWithBody request with any body + CreateThingWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateThing(ctx context.Context, body CreateThingJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) } func (c *Client) ListThings(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -109,6 +209,30 @@ func (c *Client) ListThings(ctx context.Context, params *ListThingsParams, reqEd return c.Client.Do(req) } +func (c *Client) CreateThingWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateThingRequestWithBody(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 *Client) CreateThing(ctx context.Context, body CreateThingJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateThingRequest(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) +} + // NewListThingsRequest generates requests for ListThings func NewListThingsRequest(server string, params *ListThingsParams) (*http.Request, error) { var err error @@ -175,6 +299,46 @@ func NewListThingsRequest(server string, params *ListThingsParams) (*http.Reques return req, nil } +// NewCreateThingRequest calls the generic CreateThing builder with application/json body +func NewCreateThingRequest(server string, body CreateThingJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateThingRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreateThingRequestWithBody generates requests for CreateThing with any type of body +func NewCreateThingRequestWithBody(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("/things") + 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 +} + func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { for _, r := range c.RequestEditors { if err := r(ctx, req); err != nil { @@ -220,6 +384,11 @@ func WithBaseURL(baseURL string) ClientOption { type ClientWithResponsesInterface interface { // ListThingsWithResponse request ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) + + // CreateThingWithBodyWithResponse request with any body + CreateThingWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateThingResponse, error) + + CreateThingWithResponse(ctx context.Context, body CreateThingJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateThingResponse, error) } type ListThingsResponse struct { @@ -251,6 +420,35 @@ func (r ListThingsResponse) ContentType() string { return "" } +type CreateThingResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r CreateThingResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateThingResponse) 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 CreateThingResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ListThingsWithResponse request returning *ListThingsResponse func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, params *ListThingsParams, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { rsp, err := c.ListThings(ctx, params, reqEditors...) @@ -260,6 +458,23 @@ func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, params return ParseListThingsResponse(rsp) } +// CreateThingWithBodyWithResponse request with arbitrary body returning *CreateThingResponse +func (c *ClientWithResponses) CreateThingWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateThingResponse, error) { + rsp, err := c.CreateThingWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateThingResponse(rsp) +} + +func (c *ClientWithResponses) CreateThingWithResponse(ctx context.Context, body CreateThingJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateThingResponse, error) { + rsp, err := c.CreateThing(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateThingResponse(rsp) +} + // ParseListThingsResponse parses an HTTP response from a ListThingsWithResponse call func ParseListThingsResponse(rsp *http.Response) (*ListThingsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -275,3 +490,19 @@ func ParseListThingsResponse(rsp *http.Response) (*ListThingsResponse, error) { return response, nil } + +// ParseCreateThingResponse parses an HTTP response from a CreateThingWithResponse call +func ParseCreateThingResponse(rsp *http.Response) (*CreateThingResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateThingResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} diff --git a/internal/test/issues/issue-2329/issue2329_test.go b/internal/test/issues/issue-2329/issue2329_test.go index b7456f6a5e..cb534dc05e 100644 --- a/internal/test/issues/issue-2329/issue2329_test.go +++ b/internal/test/issues/issue-2329/issue2329_test.go @@ -1,6 +1,7 @@ package issue2329 import ( + "encoding/json" "testing" "github.com/stretchr/testify/assert" @@ -45,3 +46,35 @@ func TestNewListThingsRequest(t *testing.T) { assert.Contains(t, req.URL.RawQuery, "labels=b") }) } + +// TestThingMarshalJSON verifies the body-schema custom-marshal path. The +// Thing schema has additionalProperties, so codegen emits a custom +// MarshalJSON that walks named properties one at a time. Map- and +// slice-typed properties marked with `x-go-type-skip-optional-pointer: true` +// must both be guarded by a nil-check there — otherwise an unset map +// property serialises as `"tags":null` while an unset slice property is +// omitted, producing inconsistent output for the same OpenAPI flag. +func TestThingMarshalJSON(t *testing.T) { + t.Run("zero-value Thing omits both nil map and nil slice properties", func(t *testing.T) { + b, err := json.Marshal(Thing{}) + require.NoError(t, err) + + var got map[string]json.RawMessage + require.NoError(t, json.Unmarshal(b, &got)) + + assert.NotContains(t, got, "tags", "nil map property must be omitted, not serialised as null") + assert.NotContains(t, got, "labels", "nil slice property must be omitted, not serialised as null") + }) + + t.Run("populated Thing serialises both map and slice properties", func(t *testing.T) { + thing := Thing{ + Tags: map[string]string{"color": "blue"}, + Labels: []string{"a", "b"}, + } + b, err := json.Marshal(thing) + require.NoError(t, err) + + assert.Contains(t, string(b), `"tags":{"color":"blue"}`) + assert.Contains(t, string(b), `"labels":["a","b"]`) + }) +} diff --git a/internal/test/issues/issue-2329/openapi.yaml b/internal/test/issues/issue-2329/openapi.yaml index 692bc8b1a7..43c53b5775 100644 --- a/internal/test/issues/issue-2329/openapi.yaml +++ b/internal/test/issues/issue-2329/openapi.yaml @@ -25,3 +25,30 @@ paths: responses: "200": description: OK + post: + operationId: createThing + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Thing' + responses: + "200": + description: OK +components: + schemas: + Thing: + type: object + additionalProperties: + type: string + properties: + tags: + x-go-type-skip-optional-pointer: true + type: object + additionalProperties: + type: string + labels: + x-go-type-skip-optional-pointer: true + type: array + items: + type: string diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index f9c7338161..928fad1146 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -153,15 +153,21 @@ func (p Property) HasOptionalPointer() bool { return !p.Required && !p.Schema.SkipOptionalPointer } -// ZeroValueIsNil is a helper function to determine if the given Go type used for this property -// Will return true if the OpenAPI `type` is: -// - `array` +// ZeroValueIsNil is a helper function to determine if the given Go type used +// for this property has `nil` as its Go zero value. Slices (OpenAPI `array`) +// and maps (OpenAPI `object` with only `additionalProperties`, rendered as +// `map[K]V`) both satisfy this — the custom-marshal templates use it to decide +// whether to emit a nil-check before reading the field. func (p Property) ZeroValueIsNil() bool { if p.Schema.OAPISchema == nil { return false } - return p.Schema.OAPISchema.Type.Is("array") + if p.Schema.OAPISchema.Type.Is("array") { + return true + } + + return strings.HasPrefix(p.Schema.GoType, "map[") } // EnumDefinition holds type information for enum diff --git a/pkg/codegen/schema_test.go b/pkg/codegen/schema_test.go index 6075594a32..77c1a8751a 100644 --- a/pkg/codegen/schema_test.go +++ b/pkg/codegen/schema_test.go @@ -465,6 +465,7 @@ func TestProperty_ZeroValueIsNil(t *testing.T) { tests := []struct { name string oapiSchema *openapi3.Schema + goType string expectIsNil bool }{ { @@ -477,6 +478,12 @@ func TestProperty_ZeroValueIsNil(t *testing.T) { oapiSchema: &openapi3.Schema{Type: newType("object")}, expectIsNil: false, }, + { + name: "when an object rendered as a map, returns true", + oapiSchema: &openapi3.Schema{Type: newType("object")}, + goType: "map[string]string", + expectIsNil: true, + }, { name: "when a string, returns false", oapiSchema: &openapi3.Schema{Type: newType("string")}, @@ -509,6 +516,7 @@ func TestProperty_ZeroValueIsNil(t *testing.T) { prop := Property{ Schema: Schema{ OAPISchema: tt.oapiSchema, + GoType: tt.goType, }, } if tt.expectIsNil { From 5260c72055d42244c9f4c21f8358991bb1fd43c5 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Tue, 21 Apr 2026 15:02:45 -0700 Subject: [PATCH 50/62] fix: delegate MarshalJSON on strict response types wrapping union refs When a strict-server response content schema is a $ref to a oneOf/anyOf union, the generated response type (e.g. `type X200JSONResponse Event`) is a named defined type and does not inherit Event's MarshalJSON, so json.Encode emits {} for the union's unexported raw message. Generate delegating MarshalJSON/UnmarshalJSON on the response type when the underlying schema is a ref to a union. Inline unions continue to work via the existing $hasUnionElements template branch. Fixes #970. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/test/issues/issue-970/config.yaml | 6 + internal/test/issues/issue-970/generate.go | 3 + .../test/issues/issue-970/issue970.gen.go | 375 ++++++++++++++++++ .../test/issues/issue-970/issue970_test.go | 64 +++ internal/test/issues/issue-970/spec.yaml | 33 ++ pkg/codegen/schema.go | 20 + .../strict/strict-fiber-interface.tmpl | 10 + .../templates/strict/strict-interface.tmpl | 10 + .../strict/strict-iris-interface.tmpl | 10 + .../templates/strict/strict-responses.tmpl | 10 + 10 files changed, 541 insertions(+) create mode 100644 internal/test/issues/issue-970/config.yaml create mode 100644 internal/test/issues/issue-970/generate.go create mode 100644 internal/test/issues/issue-970/issue970.gen.go create mode 100644 internal/test/issues/issue-970/issue970_test.go create mode 100644 internal/test/issues/issue-970/spec.yaml diff --git a/internal/test/issues/issue-970/config.yaml b/internal/test/issues/issue-970/config.yaml new file mode 100644 index 0000000000..d23778565d --- /dev/null +++ b/internal/test/issues/issue-970/config.yaml @@ -0,0 +1,6 @@ +package: issue970 +output: issue970.gen.go +generate: + std-http-server: true + strict-server: true + models: true diff --git a/internal/test/issues/issue-970/generate.go b/internal/test/issues/issue-970/generate.go new file mode 100644 index 0000000000..addc711e6d --- /dev/null +++ b/internal/test/issues/issue-970/generate.go @@ -0,0 +1,3 @@ +package issue970 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue-970/issue970.gen.go b/internal/test/issues/issue-970/issue970.gen.go new file mode 100644 index 0000000000..a19d0f2aae --- /dev/null +++ b/internal/test/issues/issue-970/issue970.gen.go @@ -0,0 +1,375 @@ +//go:build go1.22 + +// Package issue970 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 issue970 + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/oapi-codegen/runtime" +) + +// Defines values for OnetimeEventKind. +const ( + Onetime OnetimeEventKind = "onetime" +) + +// Valid indicates whether the value is a known member of the OnetimeEventKind enum. +func (e OnetimeEventKind) Valid() bool { + switch e { + case Onetime: + return true + default: + return false + } +} + +// Defines values for RepeatableEventKind. +const ( + Repeatable RepeatableEventKind = "repeatable" +) + +// Valid indicates whether the value is a known member of the RepeatableEventKind enum. +func (e RepeatableEventKind) Valid() bool { + switch e { + case Repeatable: + return true + default: + return false + } +} + +// Event defines model for Event. +type Event struct { + union json.RawMessage +} + +// OnetimeEvent defines model for OnetimeEvent. +type OnetimeEvent struct { + Kind OnetimeEventKind `json:"kind"` + Name string `json:"name"` +} + +// OnetimeEventKind defines model for OnetimeEvent.Kind. +type OnetimeEventKind string + +// RepeatableEvent defines model for RepeatableEvent. +type RepeatableEvent struct { + Interval string `json:"interval"` + Kind RepeatableEventKind `json:"kind"` +} + +// RepeatableEventKind defines model for RepeatableEvent.Kind. +type RepeatableEventKind string + +// AsOnetimeEvent returns the union data inside the Event as a OnetimeEvent +func (t Event) AsOnetimeEvent() (OnetimeEvent, error) { + var body OnetimeEvent + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromOnetimeEvent overwrites any union data inside the Event as the provided OnetimeEvent +func (t *Event) FromOnetimeEvent(v OnetimeEvent) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeOnetimeEvent performs a merge with any union data inside the Event, using the provided OnetimeEvent +func (t *Event) MergeOnetimeEvent(v OnetimeEvent) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsRepeatableEvent returns the union data inside the Event as a RepeatableEvent +func (t Event) AsRepeatableEvent() (RepeatableEvent, error) { + var body RepeatableEvent + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromRepeatableEvent overwrites any union data inside the Event as the provided RepeatableEvent +func (t *Event) FromRepeatableEvent(v RepeatableEvent) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeRepeatableEvent performs a merge with any union data inside the Event, using the provided RepeatableEvent +func (t *Event) MergeRepeatableEvent(v RepeatableEvent) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t Event) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *Event) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /event) + GetEvent(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 + +// GetEvent operation middleware +func (siw *ServerInterfaceWrapper) GetEvent(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetEvent(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.MethodGet+" "+options.BaseURL+"/event", wrapper.GetEvent) + + return m +} + +type GetEventRequestObject struct { +} + +type GetEventResponseObject interface { + VisitGetEventResponse(w http.ResponseWriter) error +} + +type GetEvent200JSONResponse Event + +func (t GetEvent200JSONResponse) MarshalJSON() ([]byte, error) { + return Event(t).MarshalJSON() +} + +func (t *GetEvent200JSONResponse) UnmarshalJSON(b []byte) error { + return (*Event)(t).UnmarshalJSON(b) +} + +func (response GetEvent200JSONResponse) VisitGetEventResponse(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 +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (GET /event) + GetEvent(ctx context.Context, request GetEventRequestObject) (GetEventResponseObject, 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 +} + +// GetEvent operation middleware +func (sh *strictHandler) GetEvent(w http.ResponseWriter, r *http.Request) { + var request GetEventRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetEvent(ctx, request.(GetEventRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetEvent") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetEventResponseObject); ok { + if err := validResponse.VisitGetEventResponse(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/issues/issue-970/issue970_test.go b/internal/test/issues/issue-970/issue970_test.go new file mode 100644 index 0000000000..20a5f52d43 --- /dev/null +++ b/internal/test/issues/issue-970/issue970_test.go @@ -0,0 +1,64 @@ +package issue970 + +import ( + "encoding/json" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestUnionResponseMarshalsUnderlying is a regression test for +// https://github.com/oapi-codegen/oapi-codegen/issues/970. +// +// The strict-server response type for a content schema that is a $ref to a +// oneOf/anyOf union must encode as the union's JSON, not {}. Named defined +// types do not inherit methods, so we generate a delegating MarshalJSON. +func TestUnionResponseMarshalsUnderlying(t *testing.T) { + var ev Event + require.NoError(t, ev.FromOnetimeEvent(OnetimeEvent{ + Kind: Onetime, + Name: "birthday", + })) + + resp := GetEvent200JSONResponse(ev) + + got, err := json.Marshal(resp) + require.NoError(t, err) + assert.JSONEq(t, `{"kind":"onetime","name":"birthday"}`, string(got), + "union response must marshal via delegating MarshalJSON, not as {}") +} + +// TestUnionResponseVisitWritesBody verifies the end-to-end strict-server Visit +// path — the HTTP response body must contain the union's JSON. +func TestUnionResponseVisitWritesBody(t *testing.T) { + var ev Event + require.NoError(t, ev.FromRepeatableEvent(RepeatableEvent{ + Kind: Repeatable, + Interval: "weekly", + })) + + resp := GetEvent200JSONResponse(ev) + w := httptest.NewRecorder() + + require.NoError(t, resp.VisitGetEventResponse(w)) + assert.Equal(t, 200, w.Code) + assert.Equal(t, "application/json", w.Header().Get("Content-Type")) + assert.JSONEq(t, `{"kind":"repeatable","interval":"weekly"}`, w.Body.String()) +} + +// TestUnionResponseRoundtrip verifies the delegating UnmarshalJSON also works, +// so clients parsing a response body can recover the union value. +func TestUnionResponseRoundtrip(t *testing.T) { + src := []byte(`{"kind":"onetime","name":"release"}`) + + var resp GetEvent200JSONResponse + require.NoError(t, json.Unmarshal(src, &resp)) + + ev := Event(resp) + onetime, err := ev.AsOnetimeEvent() + require.NoError(t, err) + assert.Equal(t, Onetime, onetime.Kind) + assert.Equal(t, "release", onetime.Name) +} diff --git a/internal/test/issues/issue-970/spec.yaml b/internal/test/issues/issue-970/spec.yaml new file mode 100644 index 0000000000..4bb106d74d --- /dev/null +++ b/internal/test/issues/issue-970/spec.yaml @@ -0,0 +1,33 @@ +openapi: 3.0.0 +info: + title: Issue 970 Regression + version: "1.0" +paths: + /event: + get: + operationId: getEvent + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: '#/components/schemas/Event' +components: + schemas: + Event: + oneOf: + - $ref: '#/components/schemas/OnetimeEvent' + - $ref: '#/components/schemas/RepeatableEvent' + OnetimeEvent: + type: object + required: [kind, name] + properties: + kind: { type: string, enum: [onetime] } + name: { type: string } + RepeatableEvent: + type: object + required: [kind, interval] + properties: + kind: { type: string, enum: [repeatable] } + interval: { type: string } diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 928fad1146..499a36c390 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -65,6 +65,26 @@ func (s Schema) IsExternalRef() bool { return strings.Contains(s.RefType, ".") } +// HasCustomMarshalJSON reports whether using this schema position as an +// underlying type of a named defined type (e.g. `type X Event` where Event is +// a oneOf union defined in components.schemas) would lose a custom +// MarshalJSON/UnmarshalJSON that we need to delegate to. This is true when +// the schema is a $ref to a oneOf/anyOf union defined elsewhere. +// +// It is deliberately false for inline unions: those are generated by emitting +// the union struct at this schema position, with its own MarshalJSON. The +// template's existing $hasUnionElements branch handles encoding by writing +// .union directly, so no delegation is needed. +func (s Schema) HasCustomMarshalJSON() bool { + if s.OAPISchema == nil { + return false + } + if len(s.UnionElements) > 0 { + return false + } + return len(s.OAPISchema.OneOf) > 0 || len(s.OAPISchema.AnyOf) > 0 +} + func (s Schema) TypeDecl() string { if s.IsRef() { return s.RefType diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index b4543b9b20..bcf372a35c 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -49,6 +49,16 @@ {{end}} {{else if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) -}} type {{$receiverTypeName}} {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if and .Schema.IsRef (not .Schema.IsExternalRef)}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} + {{- if and .IsJSON .Schema.HasCustomMarshalJSON}} + + func (t {{$receiverTypeName}}) MarshalJSON() ([]byte, error) { + return {{.Schema.TypeDecl}}(t).MarshalJSON() + } + + func (t *{{$receiverTypeName}}) UnmarshalJSON(b []byte) error { + return (*{{.Schema.TypeDecl}})(t).UnmarshalJSON(b) + } + {{- end}} {{else -}} type {{$receiverTypeName}} struct { Body {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{.Schema.TypeDecl}}{{else}}io.Reader{{end}} diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index a686787c13..947b781fa6 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -49,6 +49,16 @@ {{end}} {{else if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) -}} type {{$receiverTypeName}} {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if and .Schema.IsRef (not .Schema.IsExternalRef)}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} + {{- if and .IsJSON .Schema.HasCustomMarshalJSON}} + + func (t {{$receiverTypeName}}) MarshalJSON() ([]byte, error) { + return {{.Schema.TypeDecl}}(t).MarshalJSON() + } + + func (t *{{$receiverTypeName}}) UnmarshalJSON(b []byte) error { + return (*{{.Schema.TypeDecl}})(t).UnmarshalJSON(b) + } + {{- end}} {{else -}} type {{$receiverTypeName}} struct { Body {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{.Schema.TypeDecl}}{{else}}io.Reader{{end}} diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 8fcf26da1d..75b1d792ec 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -51,6 +51,16 @@ {{end}} {{else if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) -}} type {{$receiverTypeName}} {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if and .Schema.IsRef (not .Schema.IsExternalRef)}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} + {{- if and .IsJSON .Schema.HasCustomMarshalJSON}} + + func (t {{$receiverTypeName}}) MarshalJSON() ([]byte, error) { + return {{.Schema.TypeDecl}}(t).MarshalJSON() + } + + func (t *{{$receiverTypeName}}) UnmarshalJSON(b []byte) error { + return (*{{.Schema.TypeDecl}})(t).UnmarshalJSON(b) + } + {{- end}} {{else -}} type {{$receiverTypeName}} struct { Body {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{.Schema.TypeDecl}}{{else}}io.Reader{{end}} diff --git a/pkg/codegen/templates/strict/strict-responses.tmpl b/pkg/codegen/templates/strict/strict-responses.tmpl index 74f5d96494..5b4ee68c8d 100644 --- a/pkg/codegen/templates/strict/strict-responses.tmpl +++ b/pkg/codegen/templates/strict/strict-responses.tmpl @@ -12,6 +12,16 @@ {{range .Contents -}} {{if and (not $hasHeaders) (.IsSupported) -}} type {{$name}}{{.NameTagOrContentType}}Response {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if .Schema.IsRef}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} + {{- if and .IsJSON .Schema.HasCustomMarshalJSON}} + + func (t {{$name}}{{.NameTagOrContentType}}Response) MarshalJSON() ([]byte, error) { + return {{.Schema.TypeDecl}}(t).MarshalJSON() + } + + func (t *{{$name}}{{.NameTagOrContentType}}Response) UnmarshalJSON(b []byte) error { + return (*{{.Schema.TypeDecl}})(t).UnmarshalJSON(b) + } + {{- end}} {{else -}} type {{$name}}{{.NameTagOrContentType}}Response struct { Body {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{.Schema.TypeDecl}}{{else}}io.Reader{{end}} From 7787164d95fb2a983d21623c01ea19e273193274 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Mon, 23 Mar 2026 11:34:41 -0700 Subject: [PATCH 51/62] Add missing case to type generation traversal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: #1306 GenerateTypeDefsForOperation() was extracting AdditionalTypes from params and request bodies, but not from response content schemas. This meant that x-go-type-name on an inline response schema was silently ignored — the type definition was created internally but never collected for output. Add the missing loop over op.Responses[].Contents[].Schema to extract AdditionalTypes, matching the existing pattern for params and bodies. Extend the xgotypename example with a response-level x-go-type-name test case. Due to this bug, we've neglected to generate types for any types defined inline in responses, so a lot of generated files were affected due to those types being missing. Co-Authored-By: Claude Opus 4.6 (1M context) --- examples/extensions/xgotypename/api.yaml | 15 +++ examples/extensions/xgotypename/gen.go | 5 + .../test/any_of/codegen/inline/openapi.gen.go | 5 + .../issues/issue-1277/content-array.gen.go | 96 +++++++++++++++++-- .../name_conflict_resolution.gen.go | 12 +++ internal/test/strict-server/chi/server.gen.go | 2 - internal/test/strict-server/chi/types.gen.go | 3 + .../test/strict-server/client/client.gen.go | 3 + .../test/strict-server/echo/server.gen.go | 2 - internal/test/strict-server/echo/types.gen.go | 3 + .../test/strict-server/fiber/types.gen.go | 3 + internal/test/strict-server/gin/server.gen.go | 2 - internal/test/strict-server/gin/types.gen.go | 3 + .../test/strict-server/gorilla/server.gen.go | 2 - .../test/strict-server/gorilla/types.gen.go | 3 + internal/test/strict-server/iris/types.gen.go | 3 + .../test/strict-server/stdhttp/server.gen.go | 2 - .../test/strict-server/stdhttp/types.gen.go | 3 + pkg/codegen/operations.go | 6 ++ .../templates/strict/strict-interface.tmpl | 4 - 20 files changed, 157 insertions(+), 20 deletions(-) diff --git a/examples/extensions/xgotypename/api.yaml b/examples/extensions/xgotypename/api.yaml index 17b83cb0f0..6c1146a5c8 100644 --- a/examples/extensions/xgotypename/api.yaml +++ b/examples/extensions/xgotypename/api.yaml @@ -25,3 +25,18 @@ components: type: number # NOTE attempting a `x-go-type-name` here is a no-op, as we're not producing a _type_ only a _field_ x-go-type-name: ThisWillNotBeUsed +paths: + /example: + get: + operationId: exampleGet + responses: + '200': + description: "OK" + content: + 'application/json': + schema: + type: object + x-go-type-name: ResponseRenamed + properties: + name: + type: string diff --git a/examples/extensions/xgotypename/gen.go b/examples/extensions/xgotypename/gen.go index cc0c9c2bf5..aa3fe0b762 100644 --- a/examples/extensions/xgotypename/gen.go +++ b/examples/extensions/xgotypename/gen.go @@ -17,3 +17,8 @@ type ClientRenamedByExtension struct { Id *float32 `json:"id,omitempty"` Name string `json:"name"` } + +// ResponseRenamed defines parameters for ExampleGet. +type ResponseRenamed struct { + Name *string `json:"name,omitempty"` +} diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index b837299d1a..3e9467cb7f 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -48,6 +48,11 @@ type Rat struct { // apiKeyAuthContextKey is the context key for ApiKeyAuth security scheme type apiKeyAuthContextKey string +// GetPets200JSONResponse_Data_Item defines parameters for GetPets. +type GetPets200JSONResponse_Data_Item struct { + union json.RawMessage +} + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error diff --git a/internal/test/issues/issue-1277/content-array.gen.go b/internal/test/issues/issue-1277/content-array.gen.go index 8a0c29b2e3..fee7e80abb 100644 --- a/internal/test/issues/issue-1277/content-array.gen.go +++ b/internal/test/issues/issue-1277/content-array.gen.go @@ -16,6 +16,96 @@ import ( "github.com/go-chi/chi/v5" ) +// Test200JSONResponse_Item defines parameters for Test. +type Test200JSONResponse_Item struct { + Field1 *string `json:"field1,omitempty"` + Field2 *string `json:"field2,omitempty"` + AdditionalProperties map[string]interface{} `json:"-"` +} + +// Getter for additional properties for Test200JSONResponse_Item. Returns the specified +// element and whether it was found +func (a Test200JSONResponse_Item) Get(fieldName string) (value interface{}, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for Test200JSONResponse_Item +func (a *Test200JSONResponse_Item) Set(fieldName string, value interface{}) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]interface{}) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for Test200JSONResponse_Item to handle AdditionalProperties +func (a *Test200JSONResponse_Item) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["field1"]; found { + err = json.Unmarshal(raw, &a.Field1) + if err != nil { + return fmt.Errorf("error reading 'field1': %w", err) + } + delete(object, "field1") + } + + if raw, found := object["field2"]; found { + err = json.Unmarshal(raw, &a.Field2) + if err != nil { + return fmt.Errorf("error reading 'field2': %w", err) + } + delete(object, "field2") + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]interface{}) + for fieldName, fieldBuf := range object { + var fieldVal interface{} + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for Test200JSONResponse_Item to handle AdditionalProperties +func (a Test200JSONResponse_Item) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + if a.Field1 != nil { + object["field1"], err = json.Marshal(a.Field1) + if err != nil { + return nil, fmt.Errorf("error marshaling 'field1': %w", err) + } + } + + if a.Field2 != nil { + object["field2"], err = json.Marshal(a.Field2) + if err != nil { + return nil, fmt.Errorf("error marshaling 'field2': %w", err) + } + } + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -417,12 +507,6 @@ type TestResponseObject interface { type Test200JSONResponse []Test200JSONResponse_Item -type Test200JSONResponse_Item struct { - Field1 *string `json:"field1,omitempty"` - Field2 *string `json:"field2,omitempty"` - AdditionalProperties map[string]interface{} `json:"-"` -} - func (response Test200JSONResponse) VisitTestResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go index 2c42d3c71c..348bcff460 100644 --- a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -258,6 +258,18 @@ type QueryJSONBody struct { Q *string `json:"q,omitempty"` } +// PatchResource200ApplicationJSONPatchPlusJSONResponse1 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchPlusJSONResponse1 = []Resource + +// PatchResource200ApplicationJSONPatchPlusJSONResponse2 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchPlusJSONResponse2 = string + +// PatchResource200ApplicationJSONPatchQueryPlusJSONResponse1 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchQueryPlusJSONResponse1 = []Resource + +// PatchResource200ApplicationJSONPatchQueryPlusJSONResponse2 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchQueryPlusJSONResponse2 = string + // PostFooJSONRequestBody defines body for PostFoo for application/json ContentType. type PostFooJSONRequestBody PostFooJSONBody diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index e5a9ebb9d0..caf622b4b2 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -1190,8 +1190,6 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } -type UnionExample200JSONResponse0 = string - func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/chi/types.gen.go b/internal/test/strict-server/chi/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/chi/types.gen.go +++ b/internal/test/strict-server/chi/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index 72a328818a..5efe7502b1 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -39,6 +39,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 414667b5b5..3a314fb909 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -910,8 +910,6 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } -type UnionExample200JSONResponse0 = string - func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/echo/types.gen.go b/internal/test/strict-server/echo/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/echo/types.gen.go +++ b/internal/test/strict-server/echo/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/fiber/types.gen.go b/internal/test/strict-server/fiber/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/fiber/types.gen.go +++ b/internal/test/strict-server/fiber/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 0e5e4bd7f1..00ea144ab2 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -985,8 +985,6 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } -type UnionExample200JSONResponse0 = string - func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/gin/types.gen.go b/internal/test/strict-server/gin/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/gin/types.gen.go +++ b/internal/test/strict-server/gin/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 9b3f8315ea..2c28c12eb4 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -1101,8 +1101,6 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } -type UnionExample200JSONResponse0 = string - func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/gorilla/types.gen.go b/internal/test/strict-server/gorilla/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/gorilla/types.gen.go +++ b/internal/test/strict-server/gorilla/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/iris/types.gen.go b/internal/test/strict-server/iris/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/iris/types.gen.go +++ b/internal/test/strict-server/iris/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index 74e78af517..ac8d245c8d 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -1096,8 +1096,6 @@ type UnionExample200JSONResponse struct { Headers UnionExample200ResponseHeaders } -type UnionExample200JSONResponse0 = string - func (response UnionExample200JSONResponse) VisitUnionExampleResponse(w http.ResponseWriter) error { var buf bytes.Buffer diff --git a/internal/test/strict-server/stdhttp/types.gen.go b/internal/test/strict-server/stdhttp/types.gen.go index fac014c4bb..532c5ebae3 100644 --- a/internal/test/strict-server/stdhttp/types.gen.go +++ b/internal/test/strict-server/stdhttp/types.gen.go @@ -26,6 +26,9 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } +// UnionExample200JSONResponse0 defines parameters for UnionExample. +type UnionExample200JSONResponse0 = string + // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 4933e35964..0fedc32be2 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -1104,6 +1104,12 @@ func GenerateTypeDefsForOperation(op OperationDefinition) []TypeDefinition { for _, body := range op.Bodies { typeDefs = append(typeDefs, body.Schema.AdditionalTypes...) } + + for _, resp := range op.Responses { + for _, content := range resp.Contents { + typeDefs = append(typeDefs, content.Schema.AdditionalTypes...) + } + } return typeDefs } diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 947b781fa6..f722f51a91 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -80,10 +80,6 @@ } {{end}} - {{- range .Schema.AdditionalTypes}} - type {{.TypeName}} {{if .IsAlias }}={{end}} {{.Schema.TypeDecl}} - {{- end}} - func (response {{$receiverTypeName}}) Visit{{$opid}}Response(w http.ResponseWriter) error { {{if eq .NameTag "Multipart" -}} writer := multipart.NewWriter(w) From 1c89479b095e99cfe31a2f6c2d128d5ccd8ee909 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 14:27:43 -0700 Subject: [PATCH 52/62] Propagate external refs through allOf/anyOf/oneOf/not sub-schemas (#2299) When an external schema is flattened via allOf, local #/... refs nested within properties, items, additionalProperties, and composition keywords (allOf, anyOf, oneOf, not) must be rewritten to include the remote component path. Without this, generated Go code references unqualified types that don't exist in the local package. Extracts ref-rewriting into a recursive propagateRemoteRefs helper and extends it to walk the full schema tree. Fixes https://github.com/oapi-codegen/oapi-codegen/issues/2288 Co-authored-by: Claude Opus 4.6 (1M context) --- .../externalref/packageA/externalref.gen.go | 23 ++++++- internal/test/externalref/packageA/spec.yaml | 21 ++++++- .../externalref/packageB/externalref.gen.go | 61 ++++++++++++++++++- internal/test/externalref/packageB/spec.yaml | 28 +++++++++ pkg/codegen/merge_schemas.go | 49 ++++++++++++++- 5 files changed, 174 insertions(+), 8 deletions(-) diff --git a/internal/test/externalref/packageA/externalref.gen.go b/internal/test/externalref/packageA/externalref.gen.go index 582588326c..a859c18af1 100644 --- a/internal/test/externalref/packageA/externalref.gen.go +++ b/internal/test/externalref/packageA/externalref.gen.go @@ -16,18 +16,35 @@ import ( externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/externalref/packageB" ) +// EnrichedUser defines model for EnrichedUser. +type EnrichedUser struct { + ExtraField *string `json:"extra_field,omitempty"` + Id string `json:"id"` + Roles *[]externalRef0.Role `json:"roles,omitempty"` + Username string `json:"username"` +} + // ObjectA defines model for ObjectA. type ObjectA struct { Name *string `json:"name,omitempty"` ObjectB *externalRef0.ObjectB `json:"object_b,omitempty"` } +// StatusPostPayload defines model for StatusPostPayload. +type StatusPostPayload struct { + Reason *string `json:"reason,omitempty"` + Status externalRef0.StatusEnum `json:"status"` +} + // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/4yOMcrDMAxG7/L9/xjI7q25QI8QHKMkbhNZ2OpQgu5e7BS6dOikBw896UBIuyQm1gJ3", - "oISVdt/wOt0o6KWi5CSUNVIT7HeqU59CcCiaIy+wDqltjFOV/5lmOPz1n37/jvfiw90vNIxFKIznnQFm", - "1uG7+vUFa43Ic4Ljx7Z1SELsJcIBNa5rOY29AgAA//84dUj5+QAAAA==", + "H4sIAAAAAAAC/5xTzW7CMAx+F2/HSIhrbkPiDNo0LghVJnEhW5pkSToNVXn3KaEIKjqp7GbX9tfvp+1A", + "2MZZQyYG4B0EcaQGS7k0XokjyfdAPveo9aoGvu3g2VMNHJ5m19tZfzhzKD7xQIsqOBJVuU2sA+etIx8V", + "FWj6iR6rWpGWuY0nR8AhRK/MAVJilyd2/0EiQtolBqtSv+T9IZjBhkZQWH9d7fNwOuXzexaQMo+3iLEN", + "axviGk/aovyvEWegzXzEDE8YrJnswzjbqa6kO4RXq8simbYBvgWUjTLAoM3R7di9rWPCluX4BkRE9U3A", + "QJm+nIq0mQ8tHqoKZeexQG8YZvWevlrlSWaaPdxugtGXv2DIR8nRL89b3c8jNQ/SLXlco0fv8ZT7nMdf", + "oQ5VKQk36/fi8r4ytQVuWq0ZWEcGnQIOkFXHYzhP0m8AAAD//1KVtScdBAAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/externalref/packageA/spec.yaml b/internal/test/externalref/packageA/spec.yaml index b2386a097e..7b790839e5 100644 --- a/internal/test/externalref/packageA/spec.yaml +++ b/internal/test/externalref/packageA/spec.yaml @@ -5,4 +5,23 @@ components: name: type: string object_b: - $ref: ../packageB/spec.yaml#/components/schemas/ObjectB \ No newline at end of file + $ref: ../packageB/spec.yaml#/components/schemas/ObjectB + # Reproduces https://github.com/oapi-codegen/oapi-codegen/issues/2288 + # allOf extending a cross-file schema should qualify nested type refs + EnrichedUser: + allOf: + - $ref: '../packageB/spec.yaml#/components/schemas/User' + - type: object + properties: + extra_field: + type: string + # Reproduces https://github.com/oapi-codegen/oapi-codegen/issues/2288 (comment) + # allOf extending a cross-file schema whose own definition uses allOf + # with local refs — those inner refs must also be qualified. + StatusPostPayload: + allOf: + - $ref: '../packageB/spec.yaml#/components/schemas/StatusV1' + - type: object + properties: + reason: + type: string \ No newline at end of file diff --git a/internal/test/externalref/packageB/externalref.gen.go b/internal/test/externalref/packageB/externalref.gen.go index c3f879cfda..8b07f571c9 100644 --- a/internal/test/externalref/packageB/externalref.gen.go +++ b/internal/test/externalref/packageB/externalref.gen.go @@ -15,16 +15,73 @@ import ( "github.com/getkin/kin-openapi/openapi3" ) +// Defines values for Role. +const ( + RoleAdmin Role = "admin" + RoleUser Role = "user" +) + +// Valid indicates whether the value is a known member of the Role enum. +func (e Role) Valid() bool { + switch e { + case RoleAdmin: + return true + case RoleUser: + return true + default: + return false + } +} + +// Defines values for StatusEnum. +const ( + Active StatusEnum = "active" + Inactive StatusEnum = "inactive" +) + +// Valid indicates whether the value is a known member of the StatusEnum enum. +func (e StatusEnum) Valid() bool { + switch e { + case Active: + return true + case Inactive: + return true + default: + return false + } +} + // ObjectB defines model for ObjectB. type ObjectB struct { Name *string `json:"name,omitempty"` } +// Role defines model for Role. +type Role string + +// StatusEnum defines model for StatusEnum. +type StatusEnum string + +// StatusV1 defines model for StatusV1. +type StatusV1 struct { + Status StatusEnum `json:"status"` +} + +// User defines model for User. +type User struct { + Id string `json:"id"` + Roles *[]Role `json:"roles,omitempty"` + Username string `json:"username"` +} + // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/yTJwQ0CMQxE0V7mnApypAFqCNHAGm1sKzYHtNreUZa5zJfegW7DTakZqAeibxztyvvj", - "zZ63lT7NOVN4gbbB9fl1oiJyir5wrhWIPg1VP/teYE5tLqhAgbfc4i/nLwAA//8neaWPdgAAAA==", + "H4sIAAAAAAAC/4RRTUvDQBT8L6PHheB1j4LngqKX0sOavNiV/XL3rVDK/nd5a7CxtXjKhJnJm5kcMUaf", + "YqDABfqIMu7Jmw43r+808r3AlGOizJY6EYwnefIhETQKZxve0FpTeIyuUxSqh97CTN4GKNRCGTt1blF4", + "YsO1PHT5yjay/SQo2LDA696XO3Ea5zYz9PY8a+kaQbeZZmjcDKfCw9J2WKWQFpk+qs00SZTlA6f7sc+C", + "tmsKz1LrYh87/bGOQo5u4Zn8v5H6ku3nqsnZHORdlrz2A34ntxNW8ssCordhjtChOqcQEwWTLDSgkAzv", + "yzfTvgIAAP//mT+m2CQCAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/externalref/packageB/spec.yaml b/internal/test/externalref/packageB/spec.yaml index 6f90634711..95a29f9b04 100644 --- a/internal/test/externalref/packageB/spec.yaml +++ b/internal/test/externalref/packageB/spec.yaml @@ -4,3 +4,31 @@ components: properties: name: type: string + Role: + type: string + enum: [admin, user] + User: + type: object + required: [id, username] + properties: + id: + type: string + username: + type: string + roles: + type: array + items: + $ref: '#/components/schemas/Role' + StatusEnum: + type: string + enum: [active, inactive] + # StatusV1 uses allOf internally with a local ref to StatusEnum. + # This exercises the case where an external schema's own allOf + # sub-schemas contain local refs that must be rewritten. + StatusV1: + allOf: + - type: object + required: [status] + properties: + status: + $ref: '#/components/schemas/StatusEnum' diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go index bc887cfa3b..3becb5e412 100644 --- a/pkg/codegen/merge_schemas.go +++ b/pkg/codegen/merge_schemas.go @@ -168,14 +168,59 @@ func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) { } remoteComponent := pathParts[0] + propagateRemoteRefs(remoteComponent, &schema) + + return schema, nil +} + +// propagateRemoteRefs rewrites local "#/..." refs within a schema to be +// qualified with the remote component path. This is needed so that when an +// external schema is flattened via allOf, nested type references (array items, +// additionalProperties, sub-object properties) retain their external +// qualification. See https://github.com/oapi-codegen/oapi-codegen/issues/2288 +func propagateRemoteRefs(remoteComponent string, schema *openapi3.Schema) { for _, value := range schema.Properties { if len(value.Ref) > 0 && value.Ref[0] == '#' { - // local reference, should propagate remote value.Ref = remoteComponent + value.Ref + } else if value.Value != nil { + propagateRemoteRefs(remoteComponent, value.Value) } } - return schema, nil + if schema.Items != nil { + if len(schema.Items.Ref) > 0 && schema.Items.Ref[0] == '#' { + schema.Items.Ref = remoteComponent + schema.Items.Ref + } else if schema.Items.Value != nil { + propagateRemoteRefs(remoteComponent, schema.Items.Value) + } + } + + if schema.AdditionalProperties.Schema != nil { + ap := schema.AdditionalProperties.Schema + if len(ap.Ref) > 0 && ap.Ref[0] == '#' { + ap.Ref = remoteComponent + ap.Ref + } else if ap.Value != nil { + propagateRemoteRefs(remoteComponent, ap.Value) + } + } + + for _, list := range [][]*openapi3.SchemaRef{schema.AllOf, schema.AnyOf, schema.OneOf} { + for _, ref := range list { + if len(ref.Ref) > 0 && ref.Ref[0] == '#' { + ref.Ref = remoteComponent + ref.Ref + } else if ref.Value != nil { + propagateRemoteRefs(remoteComponent, ref.Value) + } + } + } + + if schema.Not != nil { + if len(schema.Not.Ref) > 0 && schema.Not.Ref[0] == '#' { + schema.Not.Ref = remoteComponent + schema.Not.Ref + } else if schema.Not.Value != nil { + propagateRemoteRefs(remoteComponent, schema.Not.Value) + } + } } func mergeAllOf(allOf []*openapi3.SchemaRef, seenSchemaRef map[string]bool) (openapi3.Schema, error) { From eff4a2be5c61df2decf16c4ac14afe8f976a1d5b Mon Sep 17 00:00:00 2001 From: Peter Turi Date: Thu, 30 Apr 2026 01:17:01 +0200 Subject: [PATCH 53/62] fix: allow x-go-type and x-go-type-skip-optional-pointer for allOf (#1610) * fix: allow x-go-type and x-go-type-skip-optional-pointer for allOf This patch ensures that if a schema is defined using allOf the main schema entry's x-go-type and x-go-type-skip-optional-pointer values are considered instead of a random allOf member's. * Add unit tests * update PR for upstream changes Address greptile review feedback and adapt to upstream main: - pkg/codegen/schema.go: simplify the allOf branch. Upstream main now catches x-go-type at the schema level via the combined extensions early return, so the PR's allOf-specific x-go-type override block is unreachable; remove it. Keep x-go-type-skip-optional-pointer propagation as a conditional override (only when the parent sets it explicitly), which preserves the decorator-idiom behavior MergeSchemas relies on for issue #1957. Read from combined extensions for parity with the rest of GenerateGoSchema. - pkg/codegen/test_specs/x-go-type-pet-allof.yaml: add trailing newline. --------- Co-authored-by: Jamie Tanna Co-authored-by: Marcin Romaszewicz Co-authored-by: Marcin Romaszewicz --- pkg/codegen/codegen_test.go | 35 ++++++++++++ pkg/codegen/schema.go | 9 +++ .../test_specs/x-go-type-pet-allof.yaml | 56 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 pkg/codegen/test_specs/x-go-type-pet-allof.yaml diff --git a/pkg/codegen/codegen_test.go b/pkg/codegen/codegen_test.go index b7b3184c3c..037c9e1886 100644 --- a/pkg/codegen/codegen_test.go +++ b/pkg/codegen/codegen_test.go @@ -173,6 +173,41 @@ func TestGoTypeImport(t *testing.T) { } } +func TestGoAllofTypeOverride(t *testing.T) { + packageName := "api" + opts := Configuration{ + PackageName: packageName, + Generate: GenerateOptions{ + EchoServer: true, + Models: true, + EmbeddedSpec: true, + }, + } + spec := "test_specs/x-go-type-pet-allof.yaml" + swagger, err := util.LoadSwagger(spec) + require.NoError(t, err) + + // Run our code generation: + code, err := Generate(swagger, opts) + assert.NoError(t, err) + assert.NotEmpty(t, code) + + // Check that we have valid (formattable) code: + _, err = format.Source([]byte(code)) + assert.NoError(t, err) + + for _, expected := range []string{ + "type Cat = cat.Cat", + "type Dog = dog.Dog", + "type Pet = pet.Pet", + "github.com/somepetproject/pkg/cat", + "github.com/somepetproject/pkg/dog", + "github.com/somepetproject/pkg/pet", + } { + assert.Contains(t, code, expected) + } +} + func TestRemoteExternalReference(t *testing.T) { if testing.Short() { t.Skip("Skipping test that interacts with the network") diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 499a36c390..4c6fc4517d 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -394,6 +394,15 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { return Schema{}, fmt.Errorf("error merging schemas: %w", err) } mergedSchema.OAPISchema = schema + // x-go-type on the parent is handled by the early return above + // (combined extensions). For x-go-type-skip-optional-pointer, only + // override the merged value when the parent sets it explicitly — + // otherwise we would clobber the value MergeSchemas computed from + // the decorator idiom (an inline allOf member that carries the + // extension; see merge_schemas.go and issue #1957). + if _, ok := extensions[extPropGoTypeSkipOptionalPointer]; ok { + mergedSchema.SkipOptionalPointer = skipOptionalPointer + } return mergedSchema, nil } diff --git a/pkg/codegen/test_specs/x-go-type-pet-allof.yaml b/pkg/codegen/test_specs/x-go-type-pet-allof.yaml new file mode 100644 index 0000000000..c2f65b90ba --- /dev/null +++ b/pkg/codegen/test_specs/x-go-type-pet-allof.yaml @@ -0,0 +1,56 @@ +paths: + /pets: + patch: + requestBody: + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + discriminator: + propertyName: pet_type + responses: + '200': + description: Updated +components: + schemas: + Pet: + x-go-type: pet.Pet + x-go-type-import: + path: github.com/somepetproject/pkg/pet + type: object + required: + - pet_type + properties: + pet_type: + type: string + discriminator: + propertyName: pet_type + Dog: # "Dog" is a value for the pet_type property (the discriminator value) + x-go-type: dog.Dog + x-go-type-import: + path: github.com/somepetproject/pkg/dog + allOf: # Combines the main `Pet` schema with `Dog`-specific properties + - $ref: '#/components/schemas/Pet' + - type: object + # all other properties specific to a `Dog` + properties: + bark: + type: boolean + breed: + type: string + enum: [Dingo, Husky, Retriever, Shepherd] + Cat: # "Cat" is a value for the pet_type property (the discriminator value) + x-go-type: cat.Cat + x-go-type-import: + path: github.com/somepetproject/pkg/cat + allOf: # Combines the main `Pet` schema with `Cat`-specific properties + - $ref: '#/components/schemas/Pet' + - type: object + # all other properties specific to a `Cat` + properties: + hunts: + type: boolean + age: + type: integer From 81b9d9525dacf7ac2dd63c1a6cd44903d21a0370 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 18:30:01 -0700 Subject: [PATCH 54/62] Overhaul anonymous schema hoisting (#2348) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING: this rename affects generated type names for inline `oneOf`, `anyOf`, and `additionalProperties` response schemas. Two prior name patterns are gone and folded into one canonical form: GetPets_200_Data_Item → GetPets200JSONResponseBody_Data_Item GetPets200JSONResponse_Data_Item → GetPets200JSONResponseBody_Data_Item The pre-existing types had no As/From/Merge accessors and the response roots were anonymous structs that could not be method-bound — that's the bug being fixed (oapi-codegen issues #1900 and #1496). User code referencing the old names could only have done so via reflection or json.RawMessage round-trips, since the types were practically unusable. The documented workaround (hoist to `#/components/schemas/` and `$ref` it) sidesteps this surface entirely, so users who hit the bug and switched to the workaround see no name change. Component schema names, `Params`, request body types, the strict envelope name `Response`, and the client-with-responses envelope name `Response` are all stable. Inline `oneOf`/`anyOf` schemas at any operation root or nested below previously bypassed the union-accessor / additionalProperties boilerplate passes, leaving generated wrapper types method-less (or, for response roots, anonymous structs that no method could be attached to). This change unifies the boilerplate-emission pipeline so every schema root — components, parameters, request bodies, response bodies — gets the same method-emitting passes. Codegen pipeline: - GenerateTypeDefinitions now builds two slices. allTypes stays components-only and feeds GenerateTypes (typedef.tmpl). boilerplateTypes is the wider set — components plus op.TypeDefinitions plus each ResponseTypeDefinition's AdditionalTypeDefinitions — and feeds the method-emitting passes (enum scanning, additionalProperties marshalers, union accessors, union+additionalProperties combined). Operation-derived types now get the same method emission as components, while declarations stay in their per-context templates. - GenerateResponseDefinitions hoists inline response-root schemas with UnionElements / HasAdditionalProperties to a synthetic TypeDefinition named ResponseBody. The strict envelope keeps its Response name and references the body type from inside (struct envelope) or as an alias (no-headers case). Two distinct names so the strict envelope never self-references. - GetResponseTypeDefinitions (client-with-responses path) computes the same body name and points the JSON field at it. - Multi-content-type disambiguation generalized: the responseTypeName itself includes the content-type tag, so separate JSON/XML/YAML content types in the same response naturally produce distinct names. New isMediaTypeSupported helper hardcodes today's expectations (intended to be user-configurable in a future change). - GenerateBodyDefinitions and GetResponseTypeDefinitions skip the local hoist when the operation came from an externally-ref'd path item — the imported package already declared the same hoisted type (PathToTypeName is deterministic), so the schema's RefType is set to externalPkg. instead. Avoids the AsExternalRef0Foo accessor names that would otherwise appear in the importing package. - New OperationDefinition.PathItemRef carries the path item ref through to GetResponseTypeDefinitions; GenerateBodyDefinitions and GenerateResponseDefinitions take it as an explicit parameter for symmetry. - ensureExternalRefsInSchema also patches UnionElements with the imported package qualifier when the enclosing schema came from an external file. - Schema.HasCustomMarshalJSON returns true for inline-but-external union shapes. The strict envelope is rendered as a defined type (`type X externalRef0.Y`), so methods on Y don't transfer; the delegator emitted by the strict template (which calls externalRef0.Y(t).MarshalJSON()) is needed for the response to serialize the union payload instead of the empty struct value. - GenerateUnionBoilerplate and GenerateUnionAndAdditionalProopertiesBoilerplate dedup by TypeName, matching the pre-existing pattern in GenerateAdditionalPropertyBoilerplate. Templates: - client-with-responses.tmpl no longer emits AdditionalTypeDefinitions declarations inline. Those nested response types now flow through op.TypeDefinitions (collected in GenerateTypeDefsForOperation by upstream PR #2284) and get declared once via param-types.tmpl with union/additionalProperties accessor methods attached. - strict-server templates (strict-interface.tmpl, strict-fiber-interface.tmpl, strict-iris-interface.tmpl) encode the response body without touching the unexported union field when the schema is from an external package — the type's MarshalJSON delegator handles it instead. Tests: - New internal/test/anonymous_inner_hoisting fixture exercises As/From/Merge round-trips on every shape: response root oneOf, response root anyOf, response items oneOf, deeply nested oneOf, request body root oneOf, request body property oneOf, plus a cross-branch Merge test. - New internal/test/issues/issue-1378/fooservice_test.go TestExternalRefUnionResponseSerialization locks in the cross-package union response serialization fix; without the HasCustomMarshalJSON change it produces `{}` instead of the union payload. Generated fixtures across internal/test and examples regenerated to reflect the new method emission and naming. Two follow-up cleanups in the strict-server templates were identified during review and deferred — extracting the .union-vs-MarshalJSON access decision into a Go-side EncodeAccessor helper, and pre-computing the full strict envelope declaration line in Go. Both are notes, not blockers. Issue #2010 (cross-module strict-server type embedding) is adjacent but a separate fix surface. Co-authored-by: Claude Opus 4.7 (1M context) --- .../test/anonymous_inner_hoisting/cfg.yaml | 5 + .../anonymous_inner_hoisting/client.gen.go | 1320 +++++++++++++++++ .../anonymous_inner_hoisting/client_test.go | 141 ++ .../test/anonymous_inner_hoisting/generate.go | 3 + .../test/anonymous_inner_hoisting/spec.yaml | 132 ++ .../test/any_of/codegen/inline/openapi.gen.go | 100 +- internal/test/components/components.gen.go | 162 +- .../issues/issue-1277/content-array.gen.go | 31 +- .../issue-1378/bionicle/bionicle.gen.go | 45 +- .../issue-1378/fooservice/fooservice.gen.go | 12 +- .../issue-1378/fooservice/fooservice_test.go | 27 + .../name_conflict_resolution.gen.go | 20 +- internal/test/strict-server/chi/server.gen.go | 4 +- internal/test/strict-server/chi/types.gen.go | 77 +- .../test/strict-server/client/client.gen.go | 80 +- .../test/strict-server/echo/server.gen.go | 4 +- internal/test/strict-server/echo/types.gen.go | 77 +- .../test/strict-server/fiber/server.gen.go | 5 +- .../test/strict-server/fiber/types.gen.go | 77 +- internal/test/strict-server/gin/server.gen.go | 4 +- internal/test/strict-server/gin/types.gen.go | 77 +- .../test/strict-server/gorilla/server.gen.go | 4 +- .../test/strict-server/gorilla/types.gen.go | 77 +- .../test/strict-server/iris/server.gen.go | 5 +- internal/test/strict-server/iris/types.gen.go | 77 +- .../test/strict-server/stdhttp/server.gen.go | 4 +- .../test/strict-server/stdhttp/types.gen.go | 77 +- pkg/codegen/codegen.go | 47 +- pkg/codegen/externalref.go | 35 +- pkg/codegen/operations.go | 182 ++- pkg/codegen/schema.go | 16 +- pkg/codegen/template_helpers.go | 22 + .../templates/client-with-responses.tmpl | 6 - .../strict/strict-fiber-interface.tmpl | 2 +- .../templates/strict/strict-interface.tmpl | 2 +- .../strict/strict-iris-interface.tmpl | 2 +- 36 files changed, 2690 insertions(+), 271 deletions(-) create mode 100644 internal/test/anonymous_inner_hoisting/cfg.yaml create mode 100644 internal/test/anonymous_inner_hoisting/client.gen.go create mode 100644 internal/test/anonymous_inner_hoisting/client_test.go create mode 100644 internal/test/anonymous_inner_hoisting/generate.go create mode 100644 internal/test/anonymous_inner_hoisting/spec.yaml create mode 100644 internal/test/issues/issue-1378/fooservice/fooservice_test.go diff --git a/internal/test/anonymous_inner_hoisting/cfg.yaml b/internal/test/anonymous_inner_hoisting/cfg.yaml new file mode 100644 index 0000000000..bbdee926a3 --- /dev/null +++ b/internal/test/anonymous_inner_hoisting/cfg.yaml @@ -0,0 +1,5 @@ +package: anonymous_inner_hoisting +output: client.gen.go +generate: + models: true + client: true diff --git a/internal/test/anonymous_inner_hoisting/client.gen.go b/internal/test/anonymous_inner_hoisting/client.gen.go new file mode 100644 index 0000000000..74fe6907c2 --- /dev/null +++ b/internal/test/anonymous_inner_hoisting/client.gen.go @@ -0,0 +1,1320 @@ +// Package anonymous_inner_hoisting 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 anonymous_inner_hoisting + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// Defines values for CatKind. +const ( + CatKindCat CatKind = "cat" +) + +// Valid indicates whether the value is a known member of the CatKind enum. +func (e CatKind) Valid() bool { + switch e { + case CatKindCat: + return true + default: + return false + } +} + +// Defines values for DogKind. +const ( + DogKindDog DogKind = "dog" +) + +// Valid indicates whether the value is a known member of the DogKind enum. +func (e DogKind) Valid() bool { + switch e { + case DogKindDog: + return true + default: + return false + } +} + +// Cat defines model for Cat. +type Cat struct { + Kind CatKind `json:"kind"` + Name *string `json:"name,omitempty"` +} + +// CatKind defines model for Cat.Kind. +type CatKind string + +// Dog defines model for Dog. +type Dog struct { + Kind DogKind `json:"kind"` + Name *string `json:"name,omitempty"` +} + +// DogKind defines model for Dog.Kind. +type DogKind string + +// PostBodyPropertyOneOfJSONBody defines parameters for PostBodyPropertyOneOf. +type PostBodyPropertyOneOfJSONBody struct { + Pet *PostBodyPropertyOneOfJSONBody_Pet `json:"pet,omitempty"` +} + +// PostBodyPropertyOneOfJSONBody_Pet defines parameters for PostBodyPropertyOneOf. +type PostBodyPropertyOneOfJSONBody_Pet struct { + union json.RawMessage +} + +// PostBodyRootOneOfJSONBody defines parameters for PostBodyRootOneOf. +type PostBodyRootOneOfJSONBody struct { + union json.RawMessage +} + +// GetResponseDeepNested200JSONResponseBody_Wrapper_Inner defines parameters for GetResponseDeepNested. +type GetResponseDeepNested200JSONResponseBody_Wrapper_Inner struct { + union json.RawMessage +} + +// GetResponseItemsOneOf200JSONResponseBody_Items_Item defines parameters for GetResponseItemsOneOf. +type GetResponseItemsOneOf200JSONResponseBody_Items_Item struct { + union json.RawMessage +} + +// GetResponseRootAnyOf200JSONResponseBody defines parameters for GetResponseRootAnyOf. +type GetResponseRootAnyOf200JSONResponseBody struct { + union json.RawMessage +} + +// GetResponseRootOneOf200JSONResponseBody defines parameters for GetResponseRootOneOf. +type GetResponseRootOneOf200JSONResponseBody struct { + union json.RawMessage +} + +// PostBodyPropertyOneOfJSONRequestBody defines body for PostBodyPropertyOneOf for application/json ContentType. +type PostBodyPropertyOneOfJSONRequestBody PostBodyPropertyOneOfJSONBody + +// PostBodyRootOneOfJSONRequestBody defines body for PostBodyRootOneOf for application/json ContentType. +type PostBodyRootOneOfJSONRequestBody PostBodyRootOneOfJSONBody + +// AsCat returns the union data inside the PostBodyPropertyOneOfJSONBody_Pet as a Cat +func (t PostBodyPropertyOneOfJSONBody_Pet) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the PostBodyPropertyOneOfJSONBody_Pet as the provided Cat +func (t *PostBodyPropertyOneOfJSONBody_Pet) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the PostBodyPropertyOneOfJSONBody_Pet, using the provided Cat +func (t *PostBodyPropertyOneOfJSONBody_Pet) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the PostBodyPropertyOneOfJSONBody_Pet as a Dog +func (t PostBodyPropertyOneOfJSONBody_Pet) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the PostBodyPropertyOneOfJSONBody_Pet as the provided Dog +func (t *PostBodyPropertyOneOfJSONBody_Pet) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the PostBodyPropertyOneOfJSONBody_Pet, using the provided Dog +func (t *PostBodyPropertyOneOfJSONBody_Pet) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t PostBodyPropertyOneOfJSONBody_Pet) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *PostBodyPropertyOneOfJSONBody_Pet) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCat returns the union data inside the PostBodyRootOneOfJSONBody as a Cat +func (t PostBodyRootOneOfJSONBody) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the PostBodyRootOneOfJSONBody as the provided Cat +func (t *PostBodyRootOneOfJSONBody) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the PostBodyRootOneOfJSONBody, using the provided Cat +func (t *PostBodyRootOneOfJSONBody) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the PostBodyRootOneOfJSONBody as a Dog +func (t PostBodyRootOneOfJSONBody) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the PostBodyRootOneOfJSONBody as the provided Dog +func (t *PostBodyRootOneOfJSONBody) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the PostBodyRootOneOfJSONBody, using the provided Dog +func (t *PostBodyRootOneOfJSONBody) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t PostBodyRootOneOfJSONBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *PostBodyRootOneOfJSONBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCat returns the union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner as a Cat +func (t GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner as the provided Cat +func (t *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner, using the provided Cat +func (t *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner as a Dog +func (t GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner as the provided Dog +func (t *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the GetResponseDeepNested200JSONResponseBody_Wrapper_Inner, using the provided Dog +func (t *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCat returns the union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item as a Cat +func (t GetResponseItemsOneOf200JSONResponseBody_Items_Item) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item as the provided Cat +func (t *GetResponseItemsOneOf200JSONResponseBody_Items_Item) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item, using the provided Cat +func (t *GetResponseItemsOneOf200JSONResponseBody_Items_Item) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item as a Dog +func (t GetResponseItemsOneOf200JSONResponseBody_Items_Item) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item as the provided Dog +func (t *GetResponseItemsOneOf200JSONResponseBody_Items_Item) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the GetResponseItemsOneOf200JSONResponseBody_Items_Item, using the provided Dog +func (t *GetResponseItemsOneOf200JSONResponseBody_Items_Item) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetResponseItemsOneOf200JSONResponseBody_Items_Item) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetResponseItemsOneOf200JSONResponseBody_Items_Item) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCat returns the union data inside the GetResponseRootAnyOf200JSONResponseBody as a Cat +func (t GetResponseRootAnyOf200JSONResponseBody) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the GetResponseRootAnyOf200JSONResponseBody as the provided Cat +func (t *GetResponseRootAnyOf200JSONResponseBody) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the GetResponseRootAnyOf200JSONResponseBody, using the provided Cat +func (t *GetResponseRootAnyOf200JSONResponseBody) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the GetResponseRootAnyOf200JSONResponseBody as a Dog +func (t GetResponseRootAnyOf200JSONResponseBody) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the GetResponseRootAnyOf200JSONResponseBody as the provided Dog +func (t *GetResponseRootAnyOf200JSONResponseBody) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the GetResponseRootAnyOf200JSONResponseBody, using the provided Dog +func (t *GetResponseRootAnyOf200JSONResponseBody) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetResponseRootAnyOf200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetResponseRootAnyOf200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCat returns the union data inside the GetResponseRootOneOf200JSONResponseBody as a Cat +func (t GetResponseRootOneOf200JSONResponseBody) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the GetResponseRootOneOf200JSONResponseBody as the provided Cat +func (t *GetResponseRootOneOf200JSONResponseBody) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the GetResponseRootOneOf200JSONResponseBody, using the provided Cat +func (t *GetResponseRootOneOf200JSONResponseBody) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the GetResponseRootOneOf200JSONResponseBody as a Dog +func (t GetResponseRootOneOf200JSONResponseBody) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the GetResponseRootOneOf200JSONResponseBody as the provided Dog +func (t *GetResponseRootOneOf200JSONResponseBody) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the GetResponseRootOneOf200JSONResponseBody, using the provided Dog +func (t *GetResponseRootOneOf200JSONResponseBody) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetResponseRootOneOf200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetResponseRootOneOf200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// 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) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client 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(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + 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 *Client) 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 *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // PostBodyPropertyOneOfWithBody request with any body + PostBodyPropertyOneOfWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostBodyPropertyOneOf(ctx context.Context, body PostBodyPropertyOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostBodyRootOneOfWithBody request with any body + PostBodyRootOneOfWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostBodyRootOneOf(ctx context.Context, body PostBodyRootOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetResponseDeepNested request + GetResponseDeepNested(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetResponseItemsOneOf request + GetResponseItemsOneOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetResponseRootAnyOf request + GetResponseRootAnyOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetResponseRootOneOf request + GetResponseRootOneOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) PostBodyPropertyOneOfWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostBodyPropertyOneOfRequestWithBody(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 *Client) PostBodyPropertyOneOf(ctx context.Context, body PostBodyPropertyOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostBodyPropertyOneOfRequest(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 *Client) PostBodyRootOneOfWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostBodyRootOneOfRequestWithBody(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 *Client) PostBodyRootOneOf(ctx context.Context, body PostBodyRootOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostBodyRootOneOfRequest(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 *Client) GetResponseDeepNested(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetResponseDeepNestedRequest(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 *Client) GetResponseItemsOneOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetResponseItemsOneOfRequest(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 *Client) GetResponseRootAnyOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetResponseRootAnyOfRequest(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 *Client) GetResponseRootOneOf(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetResponseRootOneOfRequest(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) +} + +// NewPostBodyPropertyOneOfRequest calls the generic PostBodyPropertyOneOf builder with application/json body +func NewPostBodyPropertyOneOfRequest(server string, body PostBodyPropertyOneOfJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostBodyPropertyOneOfRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostBodyPropertyOneOfRequestWithBody generates requests for PostBodyPropertyOneOf with any type of body +func NewPostBodyPropertyOneOfRequestWithBody(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("/body-property-oneof") + 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 +} + +// NewPostBodyRootOneOfRequest calls the generic PostBodyRootOneOf builder with application/json body +func NewPostBodyRootOneOfRequest(server string, body PostBodyRootOneOfJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostBodyRootOneOfRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostBodyRootOneOfRequestWithBody generates requests for PostBodyRootOneOf with any type of body +func NewPostBodyRootOneOfRequestWithBody(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("/body-root-oneof") + 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 +} + +// NewGetResponseDeepNestedRequest generates requests for GetResponseDeepNested +func NewGetResponseDeepNestedRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/response-deep-nested") + 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 +} + +// NewGetResponseItemsOneOfRequest generates requests for GetResponseItemsOneOf +func NewGetResponseItemsOneOfRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/response-items-oneof") + 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 +} + +// NewGetResponseRootAnyOfRequest generates requests for GetResponseRootAnyOf +func NewGetResponseRootAnyOfRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/response-root-anyof") + 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 +} + +// NewGetResponseRootOneOfRequest generates requests for GetResponseRootOneOf +func NewGetResponseRootOneOfRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/response-root-oneof") + 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 *Client) 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 *Client) 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 { + // PostBodyPropertyOneOfWithBodyWithResponse request with any body + PostBodyPropertyOneOfWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostBodyPropertyOneOfResponse, error) + + PostBodyPropertyOneOfWithResponse(ctx context.Context, body PostBodyPropertyOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*PostBodyPropertyOneOfResponse, error) + + // PostBodyRootOneOfWithBodyWithResponse request with any body + PostBodyRootOneOfWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostBodyRootOneOfResponse, error) + + PostBodyRootOneOfWithResponse(ctx context.Context, body PostBodyRootOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*PostBodyRootOneOfResponse, error) + + // GetResponseDeepNestedWithResponse request + GetResponseDeepNestedWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseDeepNestedResponse, error) + + // GetResponseItemsOneOfWithResponse request + GetResponseItemsOneOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseItemsOneOfResponse, error) + + // GetResponseRootAnyOfWithResponse request + GetResponseRootAnyOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseRootAnyOfResponse, error) + + // GetResponseRootOneOfWithResponse request + GetResponseRootOneOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseRootOneOfResponse, error) +} + +type PostBodyPropertyOneOfResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostBodyPropertyOneOfResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostBodyPropertyOneOfResponse) 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 PostBodyPropertyOneOfResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type PostBodyRootOneOfResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r PostBodyRootOneOfResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostBodyRootOneOfResponse) 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 PostBodyRootOneOfResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetResponseDeepNestedResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Wrapper *struct { + Inner *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner `json:"inner,omitempty"` + } `json:"wrapper,omitempty"` + } +} + +// Status returns HTTPResponse.Status +func (r GetResponseDeepNestedResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetResponseDeepNestedResponse) 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 GetResponseDeepNestedResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetResponseItemsOneOfResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Items []GetResponseItemsOneOf200JSONResponseBody_Items_Item `json:"items"` + } +} + +// Status returns HTTPResponse.Status +func (r GetResponseItemsOneOfResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetResponseItemsOneOfResponse) 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 GetResponseItemsOneOfResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetResponseRootAnyOfResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetResponseRootAnyOf200JSONResponseBody +} + +// Status returns HTTPResponse.Status +func (r GetResponseRootAnyOfResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetResponseRootAnyOfResponse) 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 GetResponseRootAnyOfResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +type GetResponseRootOneOfResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *GetResponseRootOneOf200JSONResponseBody +} + +// Status returns HTTPResponse.Status +func (r GetResponseRootOneOfResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetResponseRootOneOfResponse) 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 GetResponseRootOneOfResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + +// PostBodyPropertyOneOfWithBodyWithResponse request with arbitrary body returning *PostBodyPropertyOneOfResponse +func (c *ClientWithResponses) PostBodyPropertyOneOfWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostBodyPropertyOneOfResponse, error) { + rsp, err := c.PostBodyPropertyOneOfWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostBodyPropertyOneOfResponse(rsp) +} + +func (c *ClientWithResponses) PostBodyPropertyOneOfWithResponse(ctx context.Context, body PostBodyPropertyOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*PostBodyPropertyOneOfResponse, error) { + rsp, err := c.PostBodyPropertyOneOf(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostBodyPropertyOneOfResponse(rsp) +} + +// PostBodyRootOneOfWithBodyWithResponse request with arbitrary body returning *PostBodyRootOneOfResponse +func (c *ClientWithResponses) PostBodyRootOneOfWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostBodyRootOneOfResponse, error) { + rsp, err := c.PostBodyRootOneOfWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostBodyRootOneOfResponse(rsp) +} + +func (c *ClientWithResponses) PostBodyRootOneOfWithResponse(ctx context.Context, body PostBodyRootOneOfJSONRequestBody, reqEditors ...RequestEditorFn) (*PostBodyRootOneOfResponse, error) { + rsp, err := c.PostBodyRootOneOf(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostBodyRootOneOfResponse(rsp) +} + +// GetResponseDeepNestedWithResponse request returning *GetResponseDeepNestedResponse +func (c *ClientWithResponses) GetResponseDeepNestedWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseDeepNestedResponse, error) { + rsp, err := c.GetResponseDeepNested(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetResponseDeepNestedResponse(rsp) +} + +// GetResponseItemsOneOfWithResponse request returning *GetResponseItemsOneOfResponse +func (c *ClientWithResponses) GetResponseItemsOneOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseItemsOneOfResponse, error) { + rsp, err := c.GetResponseItemsOneOf(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetResponseItemsOneOfResponse(rsp) +} + +// GetResponseRootAnyOfWithResponse request returning *GetResponseRootAnyOfResponse +func (c *ClientWithResponses) GetResponseRootAnyOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseRootAnyOfResponse, error) { + rsp, err := c.GetResponseRootAnyOf(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetResponseRootAnyOfResponse(rsp) +} + +// GetResponseRootOneOfWithResponse request returning *GetResponseRootOneOfResponse +func (c *ClientWithResponses) GetResponseRootOneOfWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetResponseRootOneOfResponse, error) { + rsp, err := c.GetResponseRootOneOf(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetResponseRootOneOfResponse(rsp) +} + +// ParsePostBodyPropertyOneOfResponse parses an HTTP response from a PostBodyPropertyOneOfWithResponse call +func ParsePostBodyPropertyOneOfResponse(rsp *http.Response) (*PostBodyPropertyOneOfResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostBodyPropertyOneOfResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParsePostBodyRootOneOfResponse parses an HTTP response from a PostBodyRootOneOfWithResponse call +func ParsePostBodyRootOneOfResponse(rsp *http.Response) (*PostBodyRootOneOfResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostBodyRootOneOfResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetResponseDeepNestedResponse parses an HTTP response from a GetResponseDeepNestedWithResponse call +func ParseGetResponseDeepNestedResponse(rsp *http.Response) (*GetResponseDeepNestedResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetResponseDeepNestedResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Wrapper *struct { + Inner *GetResponseDeepNested200JSONResponseBody_Wrapper_Inner `json:"inner,omitempty"` + } `json:"wrapper,omitempty"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetResponseItemsOneOfResponse parses an HTTP response from a GetResponseItemsOneOfWithResponse call +func ParseGetResponseItemsOneOfResponse(rsp *http.Response) (*GetResponseItemsOneOfResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetResponseItemsOneOfResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Items []GetResponseItemsOneOf200JSONResponseBody_Items_Item `json:"items"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetResponseRootAnyOfResponse parses an HTTP response from a GetResponseRootAnyOfWithResponse call +func ParseGetResponseRootAnyOfResponse(rsp *http.Response) (*GetResponseRootAnyOfResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetResponseRootAnyOfResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetResponseRootAnyOf200JSONResponseBody + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetResponseRootOneOfResponse parses an HTTP response from a GetResponseRootOneOfWithResponse call +func ParseGetResponseRootOneOfResponse(rsp *http.Response) (*GetResponseRootOneOfResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetResponseRootOneOfResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetResponseRootOneOf200JSONResponseBody + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} diff --git a/internal/test/anonymous_inner_hoisting/client_test.go b/internal/test/anonymous_inner_hoisting/client_test.go new file mode 100644 index 0000000000..abdf532440 --- /dev/null +++ b/internal/test/anonymous_inner_hoisting/client_test.go @@ -0,0 +1,141 @@ +package anonymous_inner_hoisting + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func ptr[T any](v T) *T { return &v } + +func TestResponseRootOneOf_RoundTripCat(t *testing.T) { + cat := Cat{Kind: CatKindCat, Name: ptr("whiskers")} + + var u GetResponseRootOneOf200JSONResponseBody + require.NoError(t, u.FromCat(cat)) + + b, err := json.Marshal(u) + require.NoError(t, err) + + var decoded GetResponseRootOneOf200JSONResponseBody + require.NoError(t, json.Unmarshal(b, &decoded)) + + got, err := decoded.AsCat() + require.NoError(t, err) + require.Equal(t, cat, got) +} + +func TestResponseRootAnyOf_RoundTripDog(t *testing.T) { + dog := Dog{Kind: DogKindDog, Name: ptr("rex")} + + var u GetResponseRootAnyOf200JSONResponseBody + require.NoError(t, u.FromDog(dog)) + + b, err := json.Marshal(u) + require.NoError(t, err) + + var decoded GetResponseRootAnyOf200JSONResponseBody + require.NoError(t, json.Unmarshal(b, &decoded)) + + got, err := decoded.AsDog() + require.NoError(t, err) + require.Equal(t, dog, got) +} + +func TestResponseItemsOneOf_RoundTripBothBranches(t *testing.T) { + cat := Cat{Kind: CatKindCat, Name: ptr("whiskers")} + dog := Dog{Kind: DogKindDog, Name: ptr("rex")} + + var catItem GetResponseItemsOneOf200JSONResponseBody_Items_Item + require.NoError(t, catItem.FromCat(cat)) + var dogItem GetResponseItemsOneOf200JSONResponseBody_Items_Item + require.NoError(t, dogItem.FromDog(dog)) + + bCat, err := json.Marshal(catItem) + require.NoError(t, err) + bDog, err := json.Marshal(dogItem) + require.NoError(t, err) + + var decodedCat, decodedDog GetResponseItemsOneOf200JSONResponseBody_Items_Item + require.NoError(t, json.Unmarshal(bCat, &decodedCat)) + require.NoError(t, json.Unmarshal(bDog, &decodedDog)) + + gotCat, err := decodedCat.AsCat() + require.NoError(t, err) + require.Equal(t, cat, gotCat) + + gotDog, err := decodedDog.AsDog() + require.NoError(t, err) + require.Equal(t, dog, gotDog) +} + +func TestResponseDeepNested_RoundTrip(t *testing.T) { + cat := Cat{Kind: CatKindCat, Name: ptr("whiskers")} + + var inner GetResponseDeepNested200JSONResponseBody_Wrapper_Inner + require.NoError(t, inner.FromCat(cat)) + + b, err := json.Marshal(inner) + require.NoError(t, err) + + var decoded GetResponseDeepNested200JSONResponseBody_Wrapper_Inner + require.NoError(t, json.Unmarshal(b, &decoded)) + + got, err := decoded.AsCat() + require.NoError(t, err) + require.Equal(t, cat, got) +} + +func TestBodyRootOneOf_RoundTripCat(t *testing.T) { + cat := Cat{Kind: CatKindCat, Name: ptr("whiskers")} + + var body PostBodyRootOneOfJSONBody + require.NoError(t, body.FromCat(cat)) + + b, err := json.Marshal(body) + require.NoError(t, err) + + var decoded PostBodyRootOneOfJSONBody + require.NoError(t, json.Unmarshal(b, &decoded)) + + got, err := decoded.AsCat() + require.NoError(t, err) + require.Equal(t, cat, got) +} + +func TestBodyPropertyOneOf_RoundTripDog(t *testing.T) { + dog := Dog{Kind: DogKindDog, Name: ptr("rex")} + + var pet PostBodyPropertyOneOfJSONBody_Pet + require.NoError(t, pet.FromDog(dog)) + + b, err := json.Marshal(pet) + require.NoError(t, err) + + var decoded PostBodyPropertyOneOfJSONBody_Pet + require.NoError(t, json.Unmarshal(b, &decoded)) + + got, err := decoded.AsDog() + require.NoError(t, err) + require.Equal(t, dog, got) +} + +func TestMergeOverwritesPriorBranch(t *testing.T) { + cat := Cat{Kind: CatKindCat, Name: ptr("whiskers")} + dog := Dog{Kind: DogKindDog, Name: ptr("rex")} + + var u GetResponseRootOneOf200JSONResponseBody + require.NoError(t, u.FromCat(cat)) + require.NoError(t, u.MergeDog(dog)) + + b, err := json.Marshal(u) + require.NoError(t, err) + + var decoded GetResponseRootOneOf200JSONResponseBody + require.NoError(t, json.Unmarshal(b, &decoded)) + + gotDog, err := decoded.AsDog() + require.NoError(t, err) + require.Equal(t, dog, gotDog) +} diff --git a/internal/test/anonymous_inner_hoisting/generate.go b/internal/test/anonymous_inner_hoisting/generate.go new file mode 100644 index 0000000000..19ff037202 --- /dev/null +++ b/internal/test/anonymous_inner_hoisting/generate.go @@ -0,0 +1,3 @@ +package anonymous_inner_hoisting + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=cfg.yaml spec.yaml diff --git a/internal/test/anonymous_inner_hoisting/spec.yaml b/internal/test/anonymous_inner_hoisting/spec.yaml new file mode 100644 index 0000000000..a6febff103 --- /dev/null +++ b/internal/test/anonymous_inner_hoisting/spec.yaml @@ -0,0 +1,132 @@ +openapi: 3.0.3 +info: + version: 1.0.0 + title: Anonymous Inner Hoisting + description: | + Exercises inline oneOf / anyOf schemas at every operation root and at + nested positions. Each generated wrapper type should receive + As() / From() / Merge() accessor methods. +paths: + + /response-root-oneof: + get: + operationId: getResponseRootOneOf + responses: + '200': + description: inline oneOf as the response body root + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + + /response-root-anyof: + get: + operationId: getResponseRootAnyOf + responses: + '200': + description: inline anyOf as the response body root + content: + application/json: + schema: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + + /response-items-oneof: + get: + operationId: getResponseItemsOneOf + responses: + '200': + description: inline oneOf as items of an array property + content: + application/json: + schema: + type: object + required: + - items + properties: + items: + type: array + items: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + + /response-deep-nested: + get: + operationId: getResponseDeepNested + responses: + '200': + description: inline oneOf nested inside a property of a property + content: + application/json: + schema: + type: object + properties: + wrapper: + type: object + properties: + inner: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + + /body-root-oneof: + post: + operationId: postBodyRootOneOf + requestBody: + required: true + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + responses: + '200': + description: ok + + /body-property-oneof: + post: + operationId: postBodyPropertyOneOf + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + pet: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + responses: + '200': + description: ok + +components: + schemas: + Cat: + type: object + required: + - kind + properties: + kind: + type: string + enum: + - cat + name: + type: string + Dog: + type: object + required: + - kind + properties: + kind: + type: string + enum: + - dog + name: + type: string diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index 3e9467cb7f..fff0ef0f89 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/labstack/echo/v4" + "github.com/oapi-codegen/runtime" ) const ( @@ -48,11 +49,99 @@ type Rat struct { // apiKeyAuthContextKey is the context key for ApiKeyAuth security scheme type apiKeyAuthContextKey string -// GetPets200JSONResponse_Data_Item defines parameters for GetPets. -type GetPets200JSONResponse_Data_Item struct { +// GetPets200JSONResponseBody_Data_Item defines parameters for GetPets. +type GetPets200JSONResponseBody_Data_Item struct { union json.RawMessage } +// AsCat returns the union data inside the GetPets200JSONResponseBody_Data_Item as a Cat +func (t GetPets200JSONResponseBody_Data_Item) AsCat() (Cat, error) { + var body Cat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCat overwrites any union data inside the GetPets200JSONResponseBody_Data_Item as the provided Cat +func (t *GetPets200JSONResponseBody_Data_Item) FromCat(v Cat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCat performs a merge with any union data inside the GetPets200JSONResponseBody_Data_Item, using the provided Cat +func (t *GetPets200JSONResponseBody_Data_Item) MergeCat(v Cat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDog returns the union data inside the GetPets200JSONResponseBody_Data_Item as a Dog +func (t GetPets200JSONResponseBody_Data_Item) AsDog() (Dog, error) { + var body Dog + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDog overwrites any union data inside the GetPets200JSONResponseBody_Data_Item as the provided Dog +func (t *GetPets200JSONResponseBody_Data_Item) FromDog(v Dog) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDog performs a merge with any union data inside the GetPets200JSONResponseBody_Data_Item, using the provided Dog +func (t *GetPets200JSONResponseBody_Data_Item) MergeDog(v Dog) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsRat returns the union data inside the GetPets200JSONResponseBody_Data_Item as a Rat +func (t GetPets200JSONResponseBody_Data_Item) AsRat() (Rat, error) { + var body Rat + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromRat overwrites any union data inside the GetPets200JSONResponseBody_Data_Item as the provided Rat +func (t *GetPets200JSONResponseBody_Data_Item) FromRat(v Rat) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeRat performs a merge with any union data inside the GetPets200JSONResponseBody_Data_Item, using the provided Rat +func (t *GetPets200JSONResponseBody_Data_Item) MergeRat(v Rat) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetPets200JSONResponseBody_Data_Item) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetPets200JSONResponseBody_Data_Item) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -220,12 +309,9 @@ type GetPetsResponse struct { Body []byte HTTPResponse *http.Response JSON200 *struct { - Data *[]GetPets_200_Data_Item `json:"data,omitempty"` + Data *[]GetPets200JSONResponseBody_Data_Item `json:"data,omitempty"` } } -type GetPets_200_Data_Item struct { - union json.RawMessage -} // Status returns HTTPResponse.Status func (r GetPetsResponse) Status() string { @@ -276,7 +362,7 @@ func ParseGetPetsResponse(rsp *http.Response) (*GetPetsResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: var dest struct { - Data *[]GetPets_200_Data_Item `json:"data,omitempty"` + Data *[]GetPets200JSONResponseBody_Data_Item `json:"data,omitempty"` } if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go index e8550c87b3..c80b28dc4d 100644 --- a/internal/test/components/components.gen.go +++ b/internal/test/components/components.gen.go @@ -587,87 +587,6 @@ type EnsureEverythingIsReferencedTextRequestBody = EnsureEverythingIsReferencedT // BodyWithAddPropsJSONRequestBody defines body for BodyWithAddProps for application/json ContentType. type BodyWithAddPropsJSONRequestBody BodyWithAddPropsJSONBody -// Getter for additional properties for BodyWithAddPropsJSONBody. Returns the specified -// element and whether it was found -func (a BodyWithAddPropsJSONBody) Get(fieldName string) (value interface{}, found bool) { - if a.AdditionalProperties != nil { - value, found = a.AdditionalProperties[fieldName] - } - return -} - -// Setter for additional properties for BodyWithAddPropsJSONBody -func (a *BodyWithAddPropsJSONBody) Set(fieldName string, value interface{}) { - if a.AdditionalProperties == nil { - a.AdditionalProperties = make(map[string]interface{}) - } - a.AdditionalProperties[fieldName] = value -} - -// Override default JSON handling for BodyWithAddPropsJSONBody to handle AdditionalProperties -func (a *BodyWithAddPropsJSONBody) UnmarshalJSON(b []byte) error { - object := make(map[string]json.RawMessage) - err := json.Unmarshal(b, &object) - if err != nil { - return err - } - - if raw, found := object["inner"]; found { - err = json.Unmarshal(raw, &a.Inner) - if err != nil { - return fmt.Errorf("error reading 'inner': %w", err) - } - delete(object, "inner") - } - - if raw, found := object["name"]; found { - err = json.Unmarshal(raw, &a.Name) - if err != nil { - return fmt.Errorf("error reading 'name': %w", err) - } - delete(object, "name") - } - - if len(object) != 0 { - a.AdditionalProperties = make(map[string]interface{}) - for fieldName, fieldBuf := range object { - var fieldVal interface{} - err := json.Unmarshal(fieldBuf, &fieldVal) - if err != nil { - return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) - } - a.AdditionalProperties[fieldName] = fieldVal - } - } - return nil -} - -// Override default JSON handling for BodyWithAddPropsJSONBody to handle AdditionalProperties -func (a BodyWithAddPropsJSONBody) MarshalJSON() ([]byte, error) { - var err error - object := make(map[string]json.RawMessage) - - if a.Inner != nil { - object["inner"], err = json.Marshal(a.Inner) - if err != nil { - return nil, fmt.Errorf("error marshaling 'inner': %w", err) - } - } - - object["name"], err = json.Marshal(a.Name) - if err != nil { - return nil, fmt.Errorf("error marshaling 'name': %w", err) - } - - for fieldName, field := range a.AdditionalProperties { - object[fieldName], err = json.Marshal(field) - if err != nil { - return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) - } - } - return json.Marshal(object) -} - // Getter for additional properties for AdditionalPropertiesObject1. Returns the specified // element and whether it was found func (a AdditionalPropertiesObject1) Get(fieldName string) (value int, found bool) { @@ -990,6 +909,87 @@ func (a *OneOfObject13) Set(fieldName string, value interface{}) { a.AdditionalProperties[fieldName] = value } +// Getter for additional properties for BodyWithAddPropsJSONBody. Returns the specified +// element and whether it was found +func (a BodyWithAddPropsJSONBody) Get(fieldName string) (value interface{}, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for BodyWithAddPropsJSONBody +func (a *BodyWithAddPropsJSONBody) Set(fieldName string, value interface{}) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]interface{}) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for BodyWithAddPropsJSONBody to handle AdditionalProperties +func (a *BodyWithAddPropsJSONBody) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["inner"]; found { + err = json.Unmarshal(raw, &a.Inner) + if err != nil { + return fmt.Errorf("error reading 'inner': %w", err) + } + delete(object, "inner") + } + + if raw, found := object["name"]; found { + err = json.Unmarshal(raw, &a.Name) + if err != nil { + return fmt.Errorf("error reading 'name': %w", err) + } + delete(object, "name") + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]interface{}) + for fieldName, fieldBuf := range object { + var fieldVal interface{} + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for BodyWithAddPropsJSONBody to handle AdditionalProperties +func (a BodyWithAddPropsJSONBody) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + if a.Inner != nil { + object["inner"], err = json.Marshal(a.Inner) + if err != nil { + return nil, fmt.Errorf("error marshaling 'inner': %w", err) + } + } + + object["name"], err = json.Marshal(a.Name) + if err != nil { + return nil, fmt.Errorf("error marshaling 'name': %w", err) + } + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + // AsOneOfVariant4 returns the union data inside the AnyOfObject1 as a OneOfVariant4 func (t AnyOfObject1) AsOneOfVariant4() (OneOfVariant4, error) { var body OneOfVariant4 diff --git a/internal/test/issues/issue-1277/content-array.gen.go b/internal/test/issues/issue-1277/content-array.gen.go index fee7e80abb..4e13565987 100644 --- a/internal/test/issues/issue-1277/content-array.gen.go +++ b/internal/test/issues/issue-1277/content-array.gen.go @@ -16,32 +16,32 @@ import ( "github.com/go-chi/chi/v5" ) -// Test200JSONResponse_Item defines parameters for Test. -type Test200JSONResponse_Item struct { +// Test200JSONResponseBody_Item defines parameters for Test. +type Test200JSONResponseBody_Item struct { Field1 *string `json:"field1,omitempty"` Field2 *string `json:"field2,omitempty"` AdditionalProperties map[string]interface{} `json:"-"` } -// Getter for additional properties for Test200JSONResponse_Item. Returns the specified +// Getter for additional properties for Test200JSONResponseBody_Item. Returns the specified // element and whether it was found -func (a Test200JSONResponse_Item) Get(fieldName string) (value interface{}, found bool) { +func (a Test200JSONResponseBody_Item) Get(fieldName string) (value interface{}, found bool) { if a.AdditionalProperties != nil { value, found = a.AdditionalProperties[fieldName] } return } -// Setter for additional properties for Test200JSONResponse_Item -func (a *Test200JSONResponse_Item) Set(fieldName string, value interface{}) { +// Setter for additional properties for Test200JSONResponseBody_Item +func (a *Test200JSONResponseBody_Item) Set(fieldName string, value interface{}) { if a.AdditionalProperties == nil { a.AdditionalProperties = make(map[string]interface{}) } a.AdditionalProperties[fieldName] = value } -// Override default JSON handling for Test200JSONResponse_Item to handle AdditionalProperties -func (a *Test200JSONResponse_Item) UnmarshalJSON(b []byte) error { +// Override default JSON handling for Test200JSONResponseBody_Item to handle AdditionalProperties +func (a *Test200JSONResponseBody_Item) UnmarshalJSON(b []byte) error { object := make(map[string]json.RawMessage) err := json.Unmarshal(b, &object) if err != nil { @@ -78,8 +78,8 @@ func (a *Test200JSONResponse_Item) UnmarshalJSON(b []byte) error { return nil } -// Override default JSON handling for Test200JSONResponse_Item to handle AdditionalProperties -func (a Test200JSONResponse_Item) MarshalJSON() ([]byte, error) { +// Override default JSON handling for Test200JSONResponseBody_Item to handle AdditionalProperties +func (a Test200JSONResponseBody_Item) MarshalJSON() ([]byte, error) { var err error object := make(map[string]json.RawMessage) @@ -272,12 +272,7 @@ type ClientWithResponsesInterface interface { type TestResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *[]Test_200_Item -} -type Test_200_Item struct { - Field1 *string `json:"field1,omitempty"` - Field2 *string `json:"field2,omitempty"` - AdditionalProperties map[string]interface{} `json:"-"` + JSON200 *[]Test200JSONResponseBody_Item } // Status returns HTTPResponse.Status @@ -328,7 +323,7 @@ func ParseTestResponse(rsp *http.Response) (*TestResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest []Test_200_Item + var dest []Test200JSONResponseBody_Item if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -505,7 +500,7 @@ type TestResponseObject interface { VisitTestResponse(w http.ResponseWriter) error } -type Test200JSONResponse []Test200JSONResponse_Item +type Test200JSONResponse []Test200JSONResponseBody_Item func (response Test200JSONResponse) VisitTestResponse(w http.ResponseWriter) error { diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index f708015ae6..c9c57df5fb 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -29,6 +29,47 @@ type Bionicle struct { // BionicleName defines model for bionicleName. type BionicleName = string +// GetBionicleName400JSONResponseBody defines parameters for GetBionicleName. +type GetBionicleName400JSONResponseBody struct { + union json.RawMessage +} + +// AsBionicle returns the union data inside the GetBionicleName400JSONResponseBody as a Bionicle +func (t GetBionicleName400JSONResponseBody) AsBionicle() (Bionicle, error) { + var body Bionicle + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBionicle overwrites any union data inside the GetBionicleName400JSONResponseBody as the provided Bionicle +func (t *GetBionicleName400JSONResponseBody) FromBionicle(v Bionicle) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBionicle performs a merge with any union data inside the GetBionicleName400JSONResponseBody, using the provided Bionicle +func (t *GetBionicleName400JSONResponseBody) MergeBionicle(v Bionicle) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t GetBionicleName400JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *GetBionicleName400JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // ServerInterface represents all server handlers. type ServerInterface interface { @@ -211,9 +252,7 @@ func (response GetBionicleName200JSONResponse) VisitGetBionicleNameResponse(w ht return err } -type GetBionicleName400JSONResponse struct { - union json.RawMessage -} +type GetBionicleName400JSONResponse = GetBionicleName400JSONResponseBody func (response GetBionicleName400JSONResponse) VisitGetBionicleNameResponse(w http.ResponseWriter) error { diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index 9c856f981b..b11772fd3c 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -204,14 +204,20 @@ func (response GetBionicleName200JSONResponse) VisitGetBionicleNameResponse(w ht return err } -type GetBionicleName400JSONResponse struct { - union json.RawMessage +type GetBionicleName400JSONResponse externalRef0.GetBionicleName400JSONResponseBody + +func (t GetBionicleName400JSONResponse) MarshalJSON() ([]byte, error) { + return externalRef0.GetBionicleName400JSONResponseBody(t).MarshalJSON() +} + +func (t *GetBionicleName400JSONResponse) UnmarshalJSON(b []byte) error { + return (*externalRef0.GetBionicleName400JSONResponseBody)(t).UnmarshalJSON(b) } func (response GetBionicleName400JSONResponse) VisitGetBionicleNameResponse(w http.ResponseWriter) error { var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response.union); err != nil { + if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") diff --git a/internal/test/issues/issue-1378/fooservice/fooservice_test.go b/internal/test/issues/issue-1378/fooservice/fooservice_test.go new file mode 100644 index 0000000000..0d3319ea6b --- /dev/null +++ b/internal/test/issues/issue-1378/fooservice/fooservice_test.go @@ -0,0 +1,27 @@ +package fooservice + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + bionicle "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1378/bionicle" +) + +// TestExternalRefUnionResponseSerialization locks in the fix for the +// case where a strict-server response envelope wraps an external union +// type. Because the strict envelope is a defined type (`type X +// externalRef0.Y`), methods on Y don't transfer; without an explicit +// MarshalJSON delegator the encode falls back to struct-field +// serialization on the unexported `union` field and produces `{}`. +func TestExternalRefUnionResponseSerialization(t *testing.T) { + var body bionicle.GetBionicleName400JSONResponseBody + require.NoError(t, body.FromBionicle(bionicle.Bionicle{Name: "tahu"})) + + resp := GetBionicleName400JSONResponse(body) + + got, err := json.Marshal(resp) + require.NoError(t, err) + require.JSONEq(t, `{"name":"tahu"}`, string(got)) +} diff --git a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go index 348bcff460..b97ae67fa3 100644 --- a/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go +++ b/internal/test/name_conflict_resolution/name_conflict_resolution.gen.go @@ -258,17 +258,17 @@ type QueryJSONBody struct { Q *string `json:"q,omitempty"` } -// PatchResource200ApplicationJSONPatchPlusJSONResponse1 defines parameters for PatchResource. -type PatchResource200ApplicationJSONPatchPlusJSONResponse1 = []Resource +// PatchResource200ApplicationJSONPatchPlusJSONResponseBody1 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchPlusJSONResponseBody1 = []Resource -// PatchResource200ApplicationJSONPatchPlusJSONResponse2 defines parameters for PatchResource. -type PatchResource200ApplicationJSONPatchPlusJSONResponse2 = string +// PatchResource200ApplicationJSONPatchPlusJSONResponseBody2 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchPlusJSONResponseBody2 = string -// PatchResource200ApplicationJSONPatchQueryPlusJSONResponse1 defines parameters for PatchResource. -type PatchResource200ApplicationJSONPatchQueryPlusJSONResponse1 = []Resource +// PatchResource200ApplicationJSONPatchQueryPlusJSONResponseBody1 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchQueryPlusJSONResponseBody1 = []Resource -// PatchResource200ApplicationJSONPatchQueryPlusJSONResponse2 defines parameters for PatchResource. -type PatchResource200ApplicationJSONPatchQueryPlusJSONResponse2 = string +// PatchResource200ApplicationJSONPatchQueryPlusJSONResponseBody2 defines parameters for PatchResource. +type PatchResource200ApplicationJSONPatchQueryPlusJSONResponseBody2 = string // PostFooJSONRequestBody defines body for PostFoo for application/json ContentType. type PostFooJSONRequestBody PostFooJSONBody @@ -2308,10 +2308,6 @@ type PatchResourceResponse struct { ApplicationjsonPatchQueryJSON200 *N200ResourcePatchResponseJSON3ApplicationJSONPatchQueryPlusJSON ApplicationmergePatchJSON200 *N200ResourcePatchResponseJSON4ApplicationMergePatchPlusJSON } -type PatchResource200ApplicationJSONPatchPlusJSON1 = []Resource -type PatchResource200ApplicationJSONPatchPlusJSON2 = string -type PatchResource200ApplicationJSONPatchQueryPlusJSON1 = []Resource -type PatchResource200ApplicationJSONPatchQueryPlusJSON2 = string // Status returns HTTPResponse.Status func (r PatchResourceResponse) Status() string { diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index caf622b4b2..24563e498f 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -1184,9 +1184,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/chi/types.gen.go b/internal/test/strict-server/chi/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/chi/types.gen.go +++ b/internal/test/strict-server/chi/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index 5efe7502b1..d4cdfbc074 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -39,8 +39,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -84,6 +89,68 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -1572,11 +1639,8 @@ type UnionExampleResponse struct { Body []byte HTTPResponse *http.Response ApplicationalternativeJSON200 *Example - JSON200 *struct { - union json.RawMessage - } + JSON200 *UnionExample200JSONResponseBody } -type UnionExample2000 = string // Status returns HTTPResponse.Status func (r UnionExampleResponse) Status() string { @@ -2099,9 +2163,7 @@ func ParseUnionExampleResponse(rsp *http.Response) (*UnionExampleResponse, error response.ApplicationalternativeJSON200 = &dest case rsp.Header.Get("Content-Type") == "application/json" && rsp.StatusCode == 200: - var dest struct { - union json.RawMessage - } + var dest UnionExample200JSONResponseBody if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 3a314fb909..041e8f75d1 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -904,9 +904,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/echo/types.gen.go b/internal/test/strict-server/echo/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/echo/types.gen.go +++ b/internal/test/strict-server/echo/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index bdb00bfcdb..caea58b285 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -8,7 +8,6 @@ import ( "compress/gzip" "context" "encoding/base64" - "encoding/json" "errors" "fmt" "io" @@ -1010,9 +1009,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/fiber/types.gen.go b/internal/test/strict-server/fiber/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/fiber/types.gen.go +++ b/internal/test/strict-server/fiber/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 00ea144ab2..0642639e37 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -979,9 +979,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/gin/types.gen.go b/internal/test/strict-server/gin/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/gin/types.gen.go +++ b/internal/test/strict-server/gin/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 2c28c12eb4..85fc6fe3a9 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -1095,9 +1095,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/gorilla/types.gen.go b/internal/test/strict-server/gorilla/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/gorilla/types.gen.go +++ b/internal/test/strict-server/gorilla/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 66d0dce0bb..6bef496890 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -8,7 +8,6 @@ import ( "compress/gzip" "context" "encoding/base64" - "encoding/json" "errors" "fmt" "io" @@ -844,9 +843,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/iris/types.gen.go b/internal/test/strict-server/iris/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/iris/types.gen.go +++ b/internal/test/strict-server/iris/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index ac8d245c8d..adca621779 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -1090,9 +1090,7 @@ func (response UnionExample200ApplicationAlternativePlusJSONResponse) VisitUnion } type UnionExample200JSONResponse struct { - Body struct { - union json.RawMessage - } + Body UnionExample200JSONResponseBody Headers UnionExample200ResponseHeaders } diff --git a/internal/test/strict-server/stdhttp/types.gen.go b/internal/test/strict-server/stdhttp/types.gen.go index 532c5ebae3..08ae8548e1 100644 --- a/internal/test/strict-server/stdhttp/types.gen.go +++ b/internal/test/strict-server/stdhttp/types.gen.go @@ -3,6 +3,12 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. package api +import ( + "encoding/json" + + "github.com/oapi-codegen/runtime" +) + // Example defines model for example. type Example struct { Value *string `json:"value,omitempty"` @@ -26,8 +32,13 @@ type HeadersExampleParams struct { Header2 *int `json:"header2,omitempty"` } -// UnionExample200JSONResponse0 defines parameters for UnionExample. -type UnionExample200JSONResponse0 = string +// UnionExample200JSONResponseBody0 defines parameters for UnionExample. +type UnionExample200JSONResponseBody0 = string + +// UnionExample200JSONResponseBody defines parameters for UnionExample. +type UnionExample200JSONResponseBody struct { + union json.RawMessage +} // JSONExampleJSONRequestBody defines body for JSONExample for application/json ContentType. type JSONExampleJSONRequestBody = Example @@ -70,3 +81,65 @@ type HeadersExampleJSONRequestBody = Example // UnionExampleJSONRequestBody defines body for UnionExample for application/json ContentType. type UnionExampleJSONRequestBody = Example + +// AsUnionExample200JSONResponseBody0 returns the union data inside the UnionExample200JSONResponseBody as a UnionExample200JSONResponseBody0 +func (t UnionExample200JSONResponseBody) AsUnionExample200JSONResponseBody0() (UnionExample200JSONResponseBody0, error) { + var body UnionExample200JSONResponseBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromUnionExample200JSONResponseBody0 overwrites any union data inside the UnionExample200JSONResponseBody as the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) FromUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeUnionExample200JSONResponseBody0 performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided UnionExample200JSONResponseBody0 +func (t *UnionExample200JSONResponseBody) MergeUnionExample200JSONResponseBody0(v UnionExample200JSONResponseBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExample returns the union data inside the UnionExample200JSONResponseBody as a Example +func (t UnionExample200JSONResponseBody) AsExample() (Example, error) { + var body Example + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExample overwrites any union data inside the UnionExample200JSONResponseBody as the provided Example +func (t *UnionExample200JSONResponseBody) FromExample(v Example) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExample performs a merge with any union data inside the UnionExample200JSONResponseBody, using the provided Example +func (t *UnionExample200JSONResponseBody) MergeExample(v Example) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t UnionExample200JSONResponseBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *UnionExample200JSONResponseBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 8514ef83e1..fb588dcfa5 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -345,7 +345,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { if opts.Generate.Strict { var responses []ResponseDefinition if spec.Components != nil { - responses, err = GenerateResponseDefinitions("", spec.Components.Responses) + responses, err = GenerateResponseDefinitions("", spec.Components.Responses, "") if err != nil { return "", fmt.Errorf("error generation response definitions for schema: %w", err) } @@ -580,13 +580,28 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []Op allTypes = append(allTypes, securitySchemeTypes...) } - // Go through all operations, and add their types to allTypes, so that we can - // scan all of them for enums. Operation definitions are handled differently - // from the rest, so let's keep track of enumTypes separately, which will contain - // all types needed to be scanned for enums, which includes those within operations. - enumTypes := allTypes + // allTypes stays components-only — it's the slice passed to + // GenerateTypes (typedef.tmpl) for top-level type declarations. + // Op-derived types are declared by their per-context templates + // (param-types.tmpl, request-bodies.tmpl, client-with-responses.tmpl). + // + // boilerplateTypes is the wider universe for the method-emitting + // passes (enum scanning, additionalProperties marshalers, union + // accessors). Inline union/additionalProperties types living + // inside operations (params, request bodies, response schemas + // and any nested AdditionalTypeDefinitions) historically never + // reached these passes, so accessor methods were silently + // missing. Folding them in here is what fixes that. + boilerplateTypes := slices.Clone(allTypes) for _, op := range ops { - enumTypes = append(enumTypes, op.TypeDefinitions...) + boilerplateTypes = append(boilerplateTypes, op.TypeDefinitions...) + respDefs, err := op.GetResponseTypeDefinitions() + if err != nil { + return "", fmt.Errorf("error collecting response type definitions for %s: %w", op.OperationId, err) + } + for _, rd := range respDefs { + boilerplateTypes = append(boilerplateTypes, rd.AdditionalTypeDefinitions...) + } } operationsOut, err := GenerateTypesForOperations(t, ops) @@ -594,7 +609,7 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []Op return "", fmt.Errorf("error generating Go types for component request bodies: %w", err) } - enumsOut, err := GenerateEnums(t, enumTypes) + enumsOut, err := GenerateEnums(t, boilerplateTypes) if err != nil { return "", fmt.Errorf("error generating code for type enums: %w", err) } @@ -604,17 +619,17 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []Op return "", fmt.Errorf("error generating code for type definitions: %w", err) } - allOfBoilerplate, err := GenerateAdditionalPropertyBoilerplate(t, allTypes) + allOfBoilerplate, err := GenerateAdditionalPropertyBoilerplate(t, boilerplateTypes) if err != nil { return "", fmt.Errorf("error generating allOf boilerplate: %w", err) } - unionBoilerplate, err := GenerateUnionBoilerplate(t, allTypes) + unionBoilerplate, err := GenerateUnionBoilerplate(t, boilerplateTypes) if err != nil { return "", fmt.Errorf("error generating union boilerplate: %w", err) } - unionAndAdditionalBoilerplate, err := GenerateUnionAndAdditionalProopertiesBoilerplate(t, allTypes) + unionAndAdditionalBoilerplate, err := GenerateUnionAndAdditionalProopertiesBoilerplate(t, boilerplateTypes) if err != nil { return "", fmt.Errorf("error generating boilerplate for union types with additionalProperties: %w", err) } @@ -1120,7 +1135,12 @@ func GenerateAdditionalPropertyBoilerplate(t *template.Template, typeDefs []Type func GenerateUnionBoilerplate(t *template.Template, typeDefs []TypeDefinition) (string, error) { var filteredTypes []TypeDefinition + seen := map[string]bool{} for _, t := range typeDefs { + if seen[t.TypeName] { + continue + } + seen[t.TypeName] = true if len(t.Schema.UnionElements) != 0 { filteredTypes = append(filteredTypes, t) } @@ -1141,7 +1161,12 @@ func GenerateUnionBoilerplate(t *template.Template, typeDefs []TypeDefinition) ( func GenerateUnionAndAdditionalProopertiesBoilerplate(t *template.Template, typeDefs []TypeDefinition) (string, error) { var filteredTypes []TypeDefinition + seen := map[string]bool{} for _, t := range typeDefs { + if seen[t.TypeName] { + continue + } + seen[t.TypeName] = true if len(t.Schema.UnionElements) != 0 && t.Schema.HasAdditionalProperties { filteredTypes = append(filteredTypes, t) } diff --git a/pkg/codegen/externalref.go b/pkg/codegen/externalref.go index a48b3d4e1e..829885a5b3 100644 --- a/pkg/codegen/externalref.go +++ b/pkg/codegen/externalref.go @@ -58,6 +58,20 @@ func ensureExternalRefsInParameterDefinitions(defs *[]ParameterDefinition, ref s } } +// externalPackageFor returns the imported Go package name for a `$ref` that +// targets a file outside the current spec. Returns an empty string when the +// ref is empty, points within the current spec, or has no import-mapping. +func externalPackageFor(ref string) string { + if ref == "" { + return "" + } + parts := strings.SplitN(ref, "#", 2) + if pack, ok := globalState.importMapping[parts[0]]; ok { + return pack.Name + } + return "" +} + // ensureExternalRefsInSchema ensures that when an externalRef (`$ref` that points to a file that isn't the current spec) is encountered, we make sure we update our underlying `RefType` to make sure that we point to that type. // // This only happens if we have a non-empty `ref` passed in, and that `ref` isn't pointing to something in our file @@ -68,13 +82,26 @@ func ensureExternalRefsInSchema(schema *Schema, ref string) { return } - // if this is already defined as the start of a struct, we shouldn't inject **??** - if strings.HasPrefix(schema.GoType, "struct {") { + parts := strings.SplitN(ref, "#", 2) + pack, ok := globalState.importMapping[parts[0]] + if !ok { return } - parts := strings.SplitN(ref, "#", 2) - if pack, ok := globalState.importMapping[parts[0]]; ok { + // if this is already defined as the start of a struct, we shouldn't inject **??** + if !strings.HasPrefix(schema.GoType, "struct {") { schema.RefType = fmt.Sprintf("%s.%s", pack.Name, schema.GoType) } + + // Qualify union branch types. Each UnionElement was resolved as a + // local reference during generateUnion (e.g. "Bionicle"); when the + // enclosing schema came from an externally-ref'd file the branches + // actually live in the imported package, so the As/From/Merge + // methods generated by union.tmpl must use ".Bionicle" instead. + for i, elem := range schema.UnionElements { + s := string(elem) + if !strings.Contains(s, ".") { + schema.UnionElements[i] = UnionElement(fmt.Sprintf("%s.%s", pack.Name, s)) + } + } } diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 0fedc32be2..4087d30fec 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -329,6 +329,7 @@ type OperationDefinition struct { Spec *openapi3.Operation IsAlias bool // True when this path is a $ref alias of another path item AliasTarget string // When IsAlias is true, this is the OperationId of the canonical operation (for route registration to reference the correct wrapper) + PathItemRef string // The path item's $ref (if any); used to qualify externally-loaded schemas referenced from this operation's responses } // HandlerName returns the OperationId to use when referencing the server-side @@ -401,10 +402,10 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini // We can only generate a type if we have a value: if responseRef.Value != nil { - jsonCount := 0 + supportedCount := 0 for mediaType := range responseRef.Value.Content { - if util.IsMediaTypeJson(mediaType) { - jsonCount++ + if isMediaTypeSupported(mediaType) { + supportedCount++ } } @@ -413,57 +414,64 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini contentType := responseRef.Value.Content[contentTypeName] // We can only generate a type if we have a schema: if contentType.Schema != nil { - // When a response has multiple JSON content types (e.g., - // application/json, application/json-patch+json, and - // application/merge-patch+json), we include a content-type-derived - // segment in the schema path. This is necessary because - // GenerateGoSchema uses the path to name any inline types it - // creates (e.g., oneOf union members). Without the content type - // in the path, all content types for the same response produce - // identically-named inline types. If those content types have - // different schemas, the result is conflicting type declarations; - // if they have the same schema, the result is duplicate - // declarations. Both cases produce code that won't compile. - // - // We only add the content type segment when collision resolution - // is enabled (resolve-type-name-collisions) and jsonCount > 1, - // to avoid changing type names for existing users. Ideally the - // media type would always be part of the path for consistency. - // TODO: revisit this at the next major version change — - // always include the media type in the schema path. - schemaPath := []string{o.OperationId, responseName} - if jsonCount > 1 && util.IsMediaTypeJson(contentTypeName) && globalState.options.OutputOptions.ResolveTypeNameCollisions { - schemaPath = append(schemaPath, mediaTypeToCamelCase(contentTypeName)) - } - responseSchema, err := GenerateGoSchema(contentType.Schema, schemaPath) - if err != nil { - return nil, fmt.Errorf("unable to determine Go type for %s.%s: %w", o.OperationId, contentTypeName, err) - } - - var typeName string + var typeName, tag string switch { // HAL+JSON: case slices.Contains(contentTypesHalJSON, contentTypeName): typeName = fmt.Sprintf("HALJSON%s", nameNormalizer(responseName)) + tag = "HALJSON" case contentTypeName == "application/json": // if it's the standard application/json typeName = fmt.Sprintf("JSON%s", nameNormalizer(responseName)) + tag = "JSON" // Vendored JSON case slices.Contains(contentTypesJSON, contentTypeName) || util.IsMediaTypeJson(contentTypeName): baseTypeName := fmt.Sprintf("%s%s", nameNormalizer(contentTypeName), nameNormalizer(responseName)) typeName = strings.ReplaceAll(baseTypeName, "Json", "JSON") + tag = strings.ReplaceAll(nameNormalizer(contentTypeName), "Json", "JSON") // YAML: case slices.Contains(contentTypesYAML, contentTypeName): typeName = fmt.Sprintf("YAML%s", nameNormalizer(responseName)) + tag = "YAML" // XML: case slices.Contains(contentTypesXML, contentTypeName): typeName = fmt.Sprintf("XML%s", nameNormalizer(responseName)) + tag = "XML" default: continue } + // Use the same body-type name as the server-side + // GenerateResponseDefinitions ("Body" suffixed so it + // doesn't collide with the strict envelope's struct + // wrapper) as the schema-path root. The canonical + // declaration happens server-side; here we just point + // RefType at the same name so the JSON field + // renders as a pointer to it. + responseBodyTypeName := o.OperationId + responseName + tag + "ResponseBody" + schemaPath := []string{responseBodyTypeName} + responseSchema, err := GenerateGoSchema(contentType.Schema, schemaPath) + if err != nil { + return nil, fmt.Errorf("unable to determine Go type for %s.%s: %w", o.OperationId, contentTypeName, err) + } + + // Hoist inline response-root schemas that need + // method-emitting boilerplate (UnionElements / + // AdditionalProperties). For external path items, + // qualify with the imported package — see the + // equivalent block in GenerateResponseDefinitions for + // rationale. + if !IsGoTypeReference(responseRef.Ref) && responseSchema.RefType == "" && + (len(responseSchema.UnionElements) != 0 || responseSchema.HasAdditionalProperties) { + if externalPkg := externalPackageFor(o.PathItemRef); externalPkg != "" { + responseSchema.RefType = fmt.Sprintf("%s.%s", externalPkg, responseBodyTypeName) + } else { + responseSchema.RefType = responseBodyTypeName + } + } + td := ResponseTypeDefinition{ TypeDefinition: TypeDefinition{ TypeName: typeName, @@ -478,7 +486,7 @@ func (o *OperationDefinition) GetResponseTypeDefinitions() ([]ResponseTypeDefini if err != nil { return nil, fmt.Errorf("error dereferencing response Ref: %w", err) } - if jsonCount > 1 && util.IsMediaTypeJson(contentTypeName) { + if supportedCount > 1 { if resolved := resolvedNameForRefPath(responseRef.Ref, contentTypeName); resolved != "" { refType = resolved + mediaTypeToCamelCase(contentTypeName) } else { @@ -808,14 +816,14 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { return nil, err } - bodyDefinitions, typeDefinitions, err := GenerateBodyDefinitions(operationId, op.RequestBody) + bodyDefinitions, typeDefinitions, err := GenerateBodyDefinitions(operationId, op.RequestBody, pathItem.Ref) if err != nil { return nil, fmt.Errorf("error generating body definitions: %w", err) } ensureExternalRefsInRequestBodyDefinitions(&bodyDefinitions, pathItem.Ref) - responseDefinitions, err := GenerateResponseDefinitions(operationId, op.Responses.Map()) + responseDefinitions, err := GenerateResponseDefinitions(operationId, op.Responses.Map(), pathItem.Ref) if err != nil { return nil, fmt.Errorf("error generating response definitions: %w", err) } @@ -838,6 +846,7 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { TypeDefinitions: typeDefinitions, IsAlias: isAlias, AliasTarget: aliasTarget, + PathItemRef: pathItem.Ref, } // check for overrides of SecurityDefinitions. @@ -887,7 +896,14 @@ func generateDefaultOperationID(opName string, requestPath string) (string, erro // GenerateBodyDefinitions turns the Swagger body definitions into a list of our body // definitions which will be used for code generation. -func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBodyRef) ([]RequestBodyDefinition, []TypeDefinition, error) { +// +// pathItemRef is the path item's $ref (if any). When non-empty and pointing at +// an external file, the body type that would otherwise be hoisted locally is +// replaced by a reference to the imported package's same-named type — the +// imported package already declares it (with any As/From/Merge methods), so +// redeclaring locally would just produce an awkward duplicate with +// package-qualified union elements. +func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBodyRef, pathItemRef string) ([]RequestBodyDefinition, []TypeDefinition, error) { if bodyOrRef == nil { return nil, nil, nil } @@ -942,24 +958,31 @@ func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBody // type under #/components, we'll define a type for it, so // that we have an easy to use type for marshaling. if bodySchema.RefType == "" { - if contentType == "application/x-www-form-urlencoded" { - // Apply the appropriate structure tag if the request - // schema was defined under the operations' section. - for i := range bodySchema.Properties { - bodySchema.Properties[i].NeedsFormTag = true - } + if externalPkg := externalPackageFor(pathItemRef); externalPkg != "" { + // The operation's path item came from an external file; the + // imported package already declares this body type with the + // matching name. Reference it instead of redeclaring. + bodySchema.RefType = fmt.Sprintf("%s.%s", externalPkg, bodyTypeName) + } else { + if contentType == "application/x-www-form-urlencoded" { + // Apply the appropriate structure tag if the request + // schema was defined under the operations' section. + for i := range bodySchema.Properties { + bodySchema.Properties[i].NeedsFormTag = true + } - // Regenerate the Golang struct adding the new form tag. - bodySchema.GoType = GenStructFromSchema(bodySchema) - } + // Regenerate the Golang struct adding the new form tag. + bodySchema.GoType = GenStructFromSchema(bodySchema) + } - td := TypeDefinition{ - TypeName: bodyTypeName, - Schema: bodySchema, + td := TypeDefinition{ + TypeName: bodyTypeName, + Schema: bodySchema, + } + typeDefinitions = append(typeDefinitions, td) + // The body schema now is a reference to a type + bodySchema.RefType = bodyTypeName } - typeDefinitions = append(typeDefinitions, td) - // The body schema now is a reference to a type - bodySchema.RefType = bodyTypeName } bd := RequestBodyDefinition{ @@ -986,7 +1009,9 @@ func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBody return bodyDefinitions, typeDefinitions, nil } -func GenerateResponseDefinitions(operationID string, responses map[string]*openapi3.ResponseRef) ([]ResponseDefinition, error) { +func GenerateResponseDefinitions(operationID string, responses map[string]*openapi3.ResponseRef, pathItemRef string) ([]ResponseDefinition, error) { + externalPkg := externalPackageFor(pathItemRef) + var responseDefinitions []ResponseDefinition // do not let multiple status codes ref to same response, it will break the type switch refSet := make(map[string]struct{}) @@ -1023,11 +1048,44 @@ func GenerateResponseDefinitions(operationID string, responses map[string]*opena } responseTypeName := operationID + statusCode + tag + "Response" - contentSchema, err := GenerateGoSchema(content.Schema, []string{responseTypeName}) + // The strict-server envelope keeps the bare ...Response name + // (e.g. "GetPing200JSONResponse"); the hoisted body type is + // suffixed so the envelope can reference it without colliding + // (the strict envelope is sometimes a struct that wraps the + // body in a Body field, which would self-reference if the + // names matched). + responseBodyTypeName := responseTypeName + "Body" + contentSchema, err := GenerateGoSchema(content.Schema, []string{responseBodyTypeName}) if err != nil { return nil, fmt.Errorf("error generating request body definition: %w", err) } + // Hoist inline response-root schemas that need method-emitting + // boilerplate (UnionElements / AdditionalProperties) to a + // synthetic top-level TypeDefinition. The hoisted typedef flows + // via op.TypeDefinitions (collected in + // GenerateTypeDefsForOperation) and gets declared once via + // typedef.tmpl with full union/additionalProperties methods. + // The strict-server template references it as the body type + // from the envelope. + // + // When the operation came from an externally-ref'd path item, + // the imported package generated the same hoisted name, so we + // reference it instead of redeclaring locally. + if !IsGoTypeReference(responseOrRef.Ref) && contentSchema.RefType == "" && + (len(contentSchema.UnionElements) != 0 || contentSchema.HasAdditionalProperties) { + if externalPkg != "" { + contentSchema.RefType = fmt.Sprintf("%s.%s", externalPkg, responseBodyTypeName) + } else { + contentSchema.AdditionalTypes = append(contentSchema.AdditionalTypes, TypeDefinition{ + TypeName: responseBodyTypeName, + JsonName: responseBodyTypeName, + Schema: contentSchema, + }) + contentSchema.RefType = responseBodyTypeName + } + } + rcd := ResponseContentDefinition{ ContentType: contentType, NameTag: tag, @@ -1157,7 +1215,6 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition { s.Properties = append(s.Properties, prop) } - s.Description = op.Spec.Description s.GoType = GenStructFromSchema(s) td := TypeDefinition{ @@ -1180,25 +1237,6 @@ func GenerateTypesForOperations(t *template.Template, ops []OperationDefinition) return "", fmt.Errorf("error writing boilerplate to buffer: %w", err) } - // Generate boiler plate for all additional types. - var td []TypeDefinition - for _, op := range ops { - td = append(td, op.TypeDefinitions...) - } - - addProps, err := GenerateAdditionalPropertyBoilerplate(t, td) - if err != nil { - return "", fmt.Errorf("error generating additional properties boilerplate for operations: %w", err) - } - - if _, err := w.WriteString("\n"); err != nil { - return "", fmt.Errorf("error generating additional properties boilerplate for operations: %w", err) - } - - if _, err := w.WriteString(addProps); err != nil { - return "", fmt.Errorf("error generating additional properties boilerplate for operations: %w", err) - } - if err = w.Flush(); err != nil { return "", fmt.Errorf("error flushing output buffer for server interface: %w", err) } diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 4c6fc4517d..bf46a67a63 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -71,16 +71,22 @@ func (s Schema) IsExternalRef() bool { // MarshalJSON/UnmarshalJSON that we need to delegate to. This is true when // the schema is a $ref to a oneOf/anyOf union defined elsewhere. // -// It is deliberately false for inline unions: those are generated by emitting -// the union struct at this schema position, with its own MarshalJSON. The -// template's existing $hasUnionElements branch handles encoding by writing -// .union directly, so no delegation is needed. +// For *local* inline unions it is deliberately false: those are generated by +// emitting the union struct at this schema position, with its own +// MarshalJSON. The template's existing $hasUnionElements branch handles +// encoding by writing .union directly, so no delegation is needed. +// +// For *external* inline unions (the response-root hoist set RefType to a +// type living in an imported package), the strict envelope is rendered as a +// defined type — `type X externalRef0.Y` — and methods on Y don't transfer. +// The .union shortcut also can't reach across packages. So we still need the +// MarshalJSON delegator here, even though UnionElements is non-empty. func (s Schema) HasCustomMarshalJSON() bool { if s.OAPISchema == nil { return false } if len(s.UnionElements) > 0 { - return false + return s.IsExternalRef() } return len(s.OAPISchema.OneOf) > 0 || len(s.OAPISchema.AnyOf) > 0 } diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 3ea88718bb..1beaba0b3f 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -47,6 +47,28 @@ var ( titleCaser = cases.Title(language.English) ) +// isMediaTypeSupported reports whether code generation produces a typed +// body for this media type. Today this is the closed set of JSON / YAML / +// XML variants the response and request templates know how to handle — +// see the typeName switch in GetResponseTypeDefinitions and the body +// definition switch in GenerateBodyDefinitions. A future configuration +// option is intended to let users extend this list. +func isMediaTypeSupported(mediaType string) bool { + switch { + case slices.Contains(contentTypesHalJSON, mediaType): + return true + case slices.Contains(contentTypesJSON, mediaType): + return true + case util.IsMediaTypeJson(mediaType): + return true + case slices.Contains(contentTypesYAML, mediaType): + return true + case slices.Contains(contentTypesXML, mediaType): + return true + } + return false +} + // genParamArgs takes an array of Parameter definition, and generates a valid // Go parameter declaration from them, eg: // ", foo int, bar string, baz float32". The preceding comma is there to save diff --git a/pkg/codegen/templates/client-with-responses.tmpl b/pkg/codegen/templates/client-with-responses.tmpl index 8b5b670be6..68ad3d4355 100644 --- a/pkg/codegen/templates/client-with-responses.tmpl +++ b/pkg/codegen/templates/client-with-responses.tmpl @@ -53,12 +53,6 @@ type {{genResponseTypeName $opid | ucFirst}} struct { {{- end}} } -{{- range $responseTypeDefinitions}} - {{- range .AdditionalTypeDefinitions}} - type {{.TypeName}} {{if .IsAlias }}={{end}} {{.Schema.TypeDecl}} - {{- end}} -{{- end}} - // Status returns HTTPResponse.Status func (r {{genResponseTypeName $opid | ucFirst}}) Status() string { if r.HTTPResponse != nil { diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index bcf372a35c..5f79c84348 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -97,7 +97,7 @@ {{$hasBodyVar := or ($hasHeaders) (not $fixedStatusCode) (not .IsSupported)}} {{if .IsJSON }} {{$hasUnionElements := ne 0 (len .Schema.UnionElements)}} - return ctx.JSON(&{{if $hasBodyVar}}response.Body{{else}}response{{end}}{{if $hasUnionElements}}.union{{end}}) + return ctx.JSON(&{{if $hasBodyVar}}response.Body{{else}}response{{end}}{{if and $hasUnionElements (not .Schema.IsExternalRef)}}.union{{end}}) {{else if eq .NameTag "Text" -}} _, err := ctx.WriteString(string({{if $hasBodyVar}}response.Body{{else}}response{{end}})) return err diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index f722f51a91..25e7455081 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -88,7 +88,7 @@ {{if .IsJSON -}} {{$hasUnionElements := ne 0 (len .Schema.UnionElements) -}} var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response{{if $hasBodyVar}}.Body{{end}}{{if $hasUnionElements}}.union{{end}}); err != nil { + if err := json.NewEncoder(&buf).Encode(response{{if $hasBodyVar}}.Body{{end}}{{if and $hasUnionElements (not .Schema.IsExternalRef)}}.union{{end}}); err != nil { return err } w.Header().Set("Content-Type", {{if .HasFixedContentType }}{{.ContentType | toGoString}}{{else}}response.ContentType{{end}}) diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 75b1d792ec..32d319ed8d 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -99,7 +99,7 @@ {{$hasBodyVar := or ($hasHeaders) (not $fixedStatusCode) (not .IsSupported)}} {{if .IsJSON -}} {{$hasUnionElements := ne 0 (len .Schema.UnionElements)}} - return ctx.JSON(&{{if $hasBodyVar}}response.Body{{else}}response{{end}}{{if $hasUnionElements}}.union{{end}}) + return ctx.JSON(&{{if $hasBodyVar}}response.Body{{else}}response{{end}}{{if and $hasUnionElements (not .Schema.IsExternalRef)}}.union{{end}}) {{else if eq .NameTag "Text" -}} _, err := ctx.WriteString(string({{if $hasBodyVar}}response.Body{{else}}response{{end}})) return err From 218effec236f7f8a8dd8cfb424c7fb07756dc639 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 21:10:52 -0700 Subject: [PATCH 55/62] Synchronize strict servers (#2350) Bring the fiber and iris strict-server interface templates back into parity with the canonical stdhttp template (`strict-interface.tmpl`). Four pieces of drift were addressed: 1. Nullable / optional response-header serialization. Both templates now use the same three-way switch on `.IsNullable` / `.IsOptional` / default that PR #2301 introduced for stdhttp, so unspecified nullable values and nil optional pointers are skipped instead of being stringified into the wire header. 2. Response-header struct field types. The `{{$opid}}{{$statusCode}}ResponseHeaders` struct now uses `{{.GoTypeDef}}` (pointer/nullable-aware) rather than the raw `{{.Schema.TypeDecl}}`, matching the type that the typed-body Visit function expects. 3. `$ref` Text responses. The fixed-status-code + ref branch now matches Multipart and Text together (PR #2225), so `$ref` text responses alias directly to the component response type. Iris additionally drops its unconditional `type X string` short-circuit, which previously masked `$ref`, `$hasHeaders`, and `$fixedStatusCode` for any text response. 4. `$ref` name qualification (fiber only). Switch from `ucFirst` to `ucFirstWithPkgName` so external-ref response types carry their package qualifier, matching stdhttp and iris. Regenerated fixtures under `internal/test/strict-server/{fiber,iris}/server.gen.go` demonstrate the change for items (1) and (2); items (3) and (4) have no existing fiber/iris fixture coverage. The no-content `Visit*Response` branch still renders headers unconditionally in all three templates (including stdhttp); that gap is tracked separately (#2349) and not addressed here. Fixes: #2331 Co-authored-by: Claude Opus 4.7 (1M context) --- .../test/strict-server/fiber/server.gen.go | 12 +++++++---- .../test/strict-server/iris/server.gen.go | 12 +++++++---- .../strict/strict-fiber-interface.tmpl | 18 +++++++++++++---- .../strict/strict-iris-interface.tmpl | 20 +++++++++++++------ 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index caea58b285..71761a1541 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -945,8 +945,8 @@ type HeadersExampleResponseObject interface { type HeadersExample200ResponseHeaders struct { Header1 string Header2 int - NullableHeader string - OptionalHeader string + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -957,8 +957,12 @@ type HeadersExample200JSONResponse struct { func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(ctx *fiber.Ctx) error { ctx.Response().Header.Set("header1", fmt.Sprint(response.Headers.Header1)) ctx.Response().Header.Set("header2", fmt.Sprint(response.Headers.Header2)) - ctx.Response().Header.Set("nullable-header", fmt.Sprint(response.Headers.NullableHeader)) - ctx.Response().Header.Set("optional-header", fmt.Sprint(response.Headers.OptionalHeader)) + if response.Headers.NullableHeader != nil { + ctx.Response().Header.Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + ctx.Response().Header.Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } ctx.Response().Header.Set("Content-Type", "application/json") ctx.Status(200) diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 6bef496890..5d2dce3b6c 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -779,8 +779,8 @@ type HeadersExampleResponseObject interface { type HeadersExample200ResponseHeaders struct { Header1 string Header2 int - NullableHeader string - OptionalHeader string + NullableHeader *string + OptionalHeader *string } type HeadersExample200JSONResponse struct { @@ -791,8 +791,12 @@ type HeadersExample200JSONResponse struct { func (response HeadersExample200JSONResponse) VisitHeadersExampleResponse(ctx iris.Context) error { ctx.ResponseWriter().Header().Set("header1", fmt.Sprint(response.Headers.Header1)) ctx.ResponseWriter().Header().Set("header2", fmt.Sprint(response.Headers.Header2)) - ctx.ResponseWriter().Header().Set("nullable-header", fmt.Sprint(response.Headers.NullableHeader)) - ctx.ResponseWriter().Header().Set("optional-header", fmt.Sprint(response.Headers.OptionalHeader)) + if response.Headers.NullableHeader != nil { + ctx.ResponseWriter().Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + ctx.ResponseWriter().Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } ctx.ResponseWriter().Header().Set("Content-Type", "application/json") ctx.StatusCode(200) diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index 5f79c84348..9ff692e814 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -26,13 +26,13 @@ {{$fixedStatusCode := .HasFixedStatusCode -}} {{$isRef := .IsRef -}} {{$isExternalRef := .IsExternalRef -}} - {{$ref := .Ref | ucFirst -}} + {{$ref := .Ref | ucFirstWithPkgName -}} {{$headers := .Headers -}} {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.Schema.TypeDecl}} + {{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}} @@ -40,7 +40,7 @@ {{range .Contents}} {{$receiverTypeName := printf "%s%s%s%s" $opid $statusCode .NameTagOrContentType "Response"}} {{if and $fixedStatusCode $isRef -}} - {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (eq .NameTag "Multipart") -}} + {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}} type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response {{else if $isExternalRef -}} type {{$receiverTypeName}} struct { {{$ref}} } @@ -82,7 +82,17 @@ func (response {{$receiverTypeName}}) Visit{{$opid}}Response(ctx *fiber.Ctx) error { {{range $headers -}} - ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} {{if eq .NameTag "Multipart" -}} writer := multipart.NewWriter(ctx.Response().BodyWriter()) diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 32d319ed8d..0594e5993a 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -32,17 +32,15 @@ {{if (and $hasHeaders (not $isRef)) -}} type {{$opid}}{{$statusCode}}ResponseHeaders struct { {{range .Headers -}} - {{.GoName}} {{.Schema.TypeDecl}} + {{.GoName}} {{.GoTypeDef}} {{end -}} } {{end}} {{range .Contents}} {{$receiverTypeName := printf "%s%s%s%s" $opid $statusCode .NameTagOrContentType "Response"}} - {{if eq .NameTag "Text" -}} - type {{$receiverTypeName}} string - {{else if and $fixedStatusCode $isRef -}} - {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (eq .NameTag "Multipart") -}} + {{if and $fixedStatusCode $isRef -}} + {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}} type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response {{else if $isExternalRef -}} type {{$receiverTypeName}} struct { {{$ref}} } @@ -84,7 +82,17 @@ func (response {{$receiverTypeName}}) Visit{{$opid}}Response(ctx iris.Context) error { {{range $headers -}} - ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} {{if eq .NameTag "Multipart" -}} writer := multipart.NewWriter(ctx.ResponseWriter()) From 3338f939f211e618162b8dce75c88155e144bcb4 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Wed, 29 Apr 2026 21:26:48 -0700 Subject: [PATCH 56/62] Strict server: gate no-content response headers on nullable/optional (#2351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The no-content branch of the three strict-server interface templates (`strict-interface.tmpl`, `strict-fiber-interface.tmpl`, `strict-iris-interface.tmpl`) was rendering response headers unconditionally, missing the three-way `.IsNullable` / `.IsOptional` / default switch that PR #2301 added to the typed-body branch. Because the `{{$opid}}{{$statusCode}}ResponseHeaders` struct is shared between the typed-body and no-content branches and uses `{{.GoTypeDef}}` (since #2301 / #2331), an unset optional header field is `*string(nil)` and an unspecified nullable header is a zero `runtime.Nullable[T]`. The bare `fmt.Sprint(...)` in the no-content branch was therefore stringifying these to `` / a typed zero-value and emitting a junk header rather than omitting it. A 204-style response declaring an optional or nullable header — with the caller leaving it unset — produced a wrong header value instead of no header at all. Apply the same three-way switch to the no-content branch in all three templates so unset values are skipped, matching the typed-body branch behavior and matching what callers expect for OpenAPI `required: false` / `nullable: true` response headers. Add regression coverage: - `strict-schema.yaml` gains a `/no-content-headers` POST operation whose only response is 204 with `optional-header` (`required: false`) and `nullable-header` (`nullable: true`). - `NoContentHeaders` handler stub returning an empty `NoContentHeaders204Response{}` is wired into all seven framework server implementations (chi, echo, fiber, gin, gorilla, iris, stdhttp). - `NoContentHeadersOmitUnset` subtest added to the three `testImpl` copies (shared, stdhttp, fiber). Asserts both headers are absent from `rr.Header().Values(...)` when the response struct's header fields are left at their zero values. The shared `testImpl` covers chi, echo, gin, and iris in one place; stdhttp and fiber maintain their own copies because they live in separate test files (stdhttp because of its own go.mod, fiber because of its package boundary). Gorilla generates code but has no test driver — the handler stub is still required so the generated `StrictServerInterface` is satisfied. Fixes: #2349 Co-authored-by: Claude Opus 4.7 (1M context) --- internal/test/strict-server/chi/server.gen.go | 120 +++++++++++++++--- internal/test/strict-server/chi/server.go | 4 + .../test/strict-server/client/client.gen.go | 99 +++++++++++++++ .../test/strict-server/echo/server.gen.go | 107 +++++++++++++--- internal/test/strict-server/echo/server.go | 4 + .../strict-server/fiber/fiber_strict_test.go | 6 + .../test/strict-server/fiber/server.gen.go | 119 ++++++++++++++--- internal/test/strict-server/fiber/server.go | 4 + internal/test/strict-server/gin/server.gen.go | 112 +++++++++++++--- internal/test/strict-server/gin/server.go | 4 + .../test/strict-server/gorilla/server.gen.go | 114 ++++++++++++++--- internal/test/strict-server/gorilla/server.go | 4 + .../test/strict-server/iris/server.gen.go | 109 +++++++++++++--- internal/test/strict-server/iris/server.go | 4 + .../test/strict-server/stdhttp/server.gen.go | 113 ++++++++++++++--- internal/test/strict-server/stdhttp/server.go | 4 + .../strict-server/stdhttp/std_strict_test.go | 6 + .../test/strict-server/strict-schema.yaml | 16 +++ internal/test/strict-server/strict_test.go | 6 + .../strict/strict-fiber-interface.tmpl | 12 +- .../templates/strict/strict-interface.tmpl | 12 +- .../strict/strict-iris-interface.tmpl | 12 +- 22 files changed, 848 insertions(+), 143 deletions(-) diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index 24563e498f..cbf2515358 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -39,6 +39,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(w http.ResponseWriter, r *http.Request) + // (POST /no-content-headers) + NoContentHeaders(w http.ResponseWriter, r *http.Request) + // (POST /required-json-body) RequiredJSONBody(w http.ResponseWriter, r *http.Request) @@ -94,6 +97,11 @@ func (_ Unimplemented) MultipleRequestAndResponseTypes(w http.ResponseWriter, r w.WriteHeader(http.StatusNotImplemented) } +// (POST /no-content-headers) +func (_ Unimplemented) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + // (POST /required-json-body) func (_ Unimplemented) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) @@ -209,6 +217,20 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(w http.Respon handler.ServeHTTP(w, r) } +// NoContentHeaders operation middleware +func (siw *ServerInterfaceWrapper) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.NoContentHeaders(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { @@ -536,6 +558,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders) + }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) }) @@ -783,6 +808,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(w http.ResponseWriter) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(w http.ResponseWriter) error { + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + w.WriteHeader(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -1233,6 +1285,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1463,6 +1518,30 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(w http.ResponseWriter, } } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + var request NoContentHeadersRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx, request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(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)) + } +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { var request RequiredJSONBodyRequestObject @@ -1782,26 +1861,27 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/chi/server.go b/internal/test/strict-server/chi/server.go index 914f967268..1f4c633fae 100644 --- a/internal/test/strict-server/chi/server.go +++ b/internal/test/strict-server/chi/server.go @@ -122,6 +122,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go index d4cdfbc074..e9888963f1 100644 --- a/internal/test/strict-server/client/client.gen.go +++ b/internal/test/strict-server/client/client.gen.go @@ -244,6 +244,9 @@ type ClientInterface interface { MultipleRequestAndResponseTypesWithTextBody(ctx context.Context, body MultipleRequestAndResponseTypesTextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // NoContentHeaders request + NoContentHeaders(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + // RequiredJSONBodyWithBody request with any body RequiredJSONBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -385,6 +388,18 @@ func (c *Client) MultipleRequestAndResponseTypesWithTextBody(ctx context.Context return c.Client.Do(req) } +func (c *Client) NoContentHeaders(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewNoContentHeadersRequest(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 *Client) RequiredJSONBodyWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewRequiredJSONBodyRequestWithBody(c.Server, contentType, body) if err != nil { @@ -749,6 +764,33 @@ func NewMultipleRequestAndResponseTypesRequestWithBody(server string, contentTyp return req, nil } +// NewNoContentHeadersRequest generates requests for NoContentHeaders +func NewNoContentHeadersRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/no-content-headers") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewRequiredJSONBodyRequest calls the generic RequiredJSONBody builder with application/json body func NewRequiredJSONBodyRequest(server string, body RequiredJSONBodyJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -1208,6 +1250,9 @@ type ClientWithResponsesInterface interface { MultipleRequestAndResponseTypesWithTextBodyWithResponse(ctx context.Context, body MultipleRequestAndResponseTypesTextRequestBody, reqEditors ...RequestEditorFn) (*MultipleRequestAndResponseTypesResponse, error) + // NoContentHeadersWithResponse request + NoContentHeadersWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*NoContentHeadersResponse, error) + // RequiredJSONBodyWithBodyWithResponse request with any body RequiredJSONBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RequiredJSONBodyResponse, error) @@ -1371,6 +1416,35 @@ func (r MultipleRequestAndResponseTypesResponse) ContentType() string { return "" } +type NoContentHeadersResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r NoContentHeadersResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r NoContentHeadersResponse) 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 NoContentHeadersResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type RequiredJSONBodyResponse struct { Body []byte HTTPResponse *http.Response @@ -1734,6 +1808,15 @@ func (c *ClientWithResponses) MultipleRequestAndResponseTypesWithTextBodyWithRes return ParseMultipleRequestAndResponseTypesResponse(rsp) } +// NoContentHeadersWithResponse request returning *NoContentHeadersResponse +func (c *ClientWithResponses) NoContentHeadersWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*NoContentHeadersResponse, error) { + rsp, err := c.NoContentHeaders(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseNoContentHeadersResponse(rsp) +} + // RequiredJSONBodyWithBodyWithResponse request with arbitrary body returning *RequiredJSONBodyResponse func (c *ClientWithResponses) RequiredJSONBodyWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RequiredJSONBodyResponse, error) { rsp, err := c.RequiredJSONBodyWithBody(ctx, contentType, body, reqEditors...) @@ -1967,6 +2050,22 @@ func ParseMultipleRequestAndResponseTypesResponse(rsp *http.Response) (*Multiple return response, nil } +// ParseNoContentHeadersResponse parses an HTTP response from a NoContentHeadersWithResponse call +func ParseNoContentHeadersResponse(rsp *http.Response) (*NoContentHeadersResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &NoContentHeadersResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseRequiredJSONBodyResponse parses an HTTP response from a RequiredJSONBodyWithResponse call func ParseRequiredJSONBodyResponse(rsp *http.Response) (*RequiredJSONBodyResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 041e8f75d1..be6d0687fc 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -39,6 +39,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx echo.Context) error + // (POST /no-content-headers) + NoContentHeaders(ctx echo.Context) error + // (POST /required-json-body) RequiredJSONBody(ctx echo.Context) error @@ -111,6 +114,15 @@ func (w *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(ctx echo.Contex return err } +// NoContentHeaders converts echo context to params. +func (w *ServerInterfaceWrapper) NoContentHeaders(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.NoContentHeaders(ctx) + return err +} + // RequiredJSONBody converts echo context to params. func (w *ServerInterfaceWrapper) RequiredJSONBody(ctx echo.Context) error { var err error @@ -277,6 +289,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.POST(baseURL+"/multipart", wrapper.MultipartExample) router.POST(baseURL+"/multipart-related", wrapper.MultipartRelatedExample) router.POST(baseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + router.POST(baseURL+"/no-content-headers", wrapper.NoContentHeaders) router.POST(baseURL+"/required-json-body", wrapper.RequiredJSONBody) router.POST(baseURL+"/required-text-body", wrapper.RequiredTextBody) router.GET(baseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters) @@ -503,6 +516,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(w http.ResponseWriter) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(w http.ResponseWriter) error { + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + w.WriteHeader(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -953,6 +993,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1153,6 +1196,29 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx echo.Context) error return nil } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(ctx echo.Context) error { + var request NoContentHeadersRequestObject + + handler := func(ctx echo.Context, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx.Request().Context(), request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(ctx, request) + + if err != nil { + return err + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + return validResponse.VisitNoContentHeadersResponse(ctx.Response()) + } else if response != nil { + return fmt.Errorf("unexpected response type: %T", response) + } + return nil +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(ctx echo.Context) error { var request RequiredJSONBodyRequestObject @@ -1455,26 +1521,27 @@ func (sh *strictHandler) UnionExample(ctx echo.Context) error { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/echo/server.go b/internal/test/strict-server/echo/server.go index 914f967268..1f4c633fae 100644 --- a/internal/test/strict-server/echo/server.go +++ b/internal/test/strict-server/echo/server.go @@ -122,6 +122,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/fiber/fiber_strict_test.go b/internal/test/strict-server/fiber/fiber_strict_test.go index cb8b509b08..473aa394f8 100644 --- a/internal/test/strict-server/fiber/fiber_strict_test.go +++ b/internal/test/strict-server/fiber/fiber_strict_test.go @@ -196,6 +196,12 @@ func testImpl(t *testing.T, handler http.Handler) { assert.Equal(t, header1, rr.Header().Get("header1")) assert.Equal(t, header2, rr.Header().Get("header2")) }) + t.Run("NoContentHeadersOmitUnset", func(t *testing.T) { + rr := testutil.NewRequest().Post("/no-content-headers").GoWithHTTPHandler(t, handler).Recorder + assert.Equal(t, http.StatusNoContent, rr.Code) + assert.Empty(t, rr.Header().Values("optional-header"), "optional-header should be omitted when the response field is nil") + assert.Empty(t, rr.Header().Values("nullable-header"), "nullable-header should be omitted when the response field is unspecified") + }) t.Run("UnspecifiedContentType", func(t *testing.T) { data := []byte("image data") contentType := "image/jpeg" diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index 71761a1541..9b887e72ae 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -38,6 +38,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(c *fiber.Ctx) error + // (POST /no-content-headers) + NoContentHeaders(c *fiber.Ctx) error + // (POST /required-json-body) RequiredJSONBody(c *fiber.Ctx) error @@ -150,6 +153,24 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(c *fiber.Ctx) return handler(c) } +// NoContentHeaders operation middleware +func (siw *ServerInterfaceWrapper) NoContentHeaders(c *fiber.Ctx) error { + + handler := func(c *fiber.Ctx) error { + return siw.Handler.NoContentHeaders(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) +} + // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(c *fiber.Ctx) error { @@ -417,6 +438,8 @@ func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, option router.Post(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + router.Post(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders) + router.Post(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) router.Post(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) @@ -637,6 +660,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(ctx *fiber.Ctx) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(ctx *fiber.Ctx) error { + if response.Headers.NullableHeader != nil { + ctx.Response().Header.Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + ctx.Response().Header.Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + ctx.Status(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -1057,6 +1107,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1251,6 +1304,31 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *fiber.Ctx) error { return nil } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(ctx *fiber.Ctx) error { + var request NoContentHeadersRequestObject + + handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx.UserContext(), request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(ctx, request) + + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(ctx); err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } + } else if response != nil { + return fmt.Errorf("unexpected response type: %T", response) + } + return nil +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(ctx *fiber.Ctx) error { var request RequiredJSONBodyRequestObject @@ -1563,26 +1641,27 @@ func (sh *strictHandler) UnionExample(ctx *fiber.Ctx) error { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/fiber/server.go b/internal/test/strict-server/fiber/server.go index 914f967268..1f4c633fae 100644 --- a/internal/test/strict-server/fiber/server.go +++ b/internal/test/strict-server/fiber/server.go @@ -122,6 +122,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 0642639e37..076105a01a 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -39,6 +39,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(c *gin.Context) + // (POST /no-content-headers) + NoContentHeaders(c *gin.Context) + // (POST /required-json-body) RequiredJSONBody(c *gin.Context) @@ -131,6 +134,19 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(c *gin.Contex siw.Handler.MultipleRequestAndResponseTypes(c) } +// NoContentHeaders operation middleware +func (siw *ServerInterfaceWrapper) NoContentHeaders(c *gin.Context) { + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.NoContentHeaders(c) +} + // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(c *gin.Context) { @@ -353,6 +369,7 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.POST(options.BaseURL+"/multipart", wrapper.MultipartExample) router.POST(options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample) router.POST(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + router.POST(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders) router.POST(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) router.POST(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) router.GET(options.BaseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters) @@ -578,6 +595,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(w http.ResponseWriter) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(w http.ResponseWriter) error { + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + w.WriteHeader(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -1028,6 +1072,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1286,6 +1333,30 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) { } } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(ctx *gin.Context) { + var request NoContentHeadersRequestObject + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx, request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(ctx, request) + + if err != nil { + sh.options.HandlerErrorFunc(ctx, err) + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(ctx.Writer); err != nil { + sh.options.ResponseErrorHandlerFunc(ctx, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(ctx, fmt.Errorf("unexpected response type: %T", response)) + } +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(ctx *gin.Context) { var request RequiredJSONBodyRequestObject @@ -1605,26 +1676,27 @@ func (sh *strictHandler) UnionExample(ctx *gin.Context) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/gin/server.go b/internal/test/strict-server/gin/server.go index 914f967268..1f4c633fae 100644 --- a/internal/test/strict-server/gin/server.go +++ b/internal/test/strict-server/gin/server.go @@ -122,6 +122,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index 85fc6fe3a9..c7ee8ecea4 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -39,6 +39,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(w http.ResponseWriter, r *http.Request) + // (POST /no-content-headers) + NoContentHeaders(w http.ResponseWriter, r *http.Request) + // (POST /required-json-body) RequiredJSONBody(w http.ResponseWriter, r *http.Request) @@ -135,6 +138,20 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(w http.Respon handler.ServeHTTP(w, r) } +// NoContentHeaders operation middleware +func (siw *ServerInterfaceWrapper) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.NoContentHeaders(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { @@ -458,6 +475,8 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H r.HandleFunc(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes).Methods(http.MethodPost) + r.HandleFunc(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders).Methods(http.MethodPost) + r.HandleFunc(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody).Methods(http.MethodPost) r.HandleFunc(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody).Methods(http.MethodPost) @@ -694,6 +713,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(w http.ResponseWriter) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(w http.ResponseWriter) error { + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + w.WriteHeader(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -1144,6 +1190,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1374,6 +1423,30 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(w http.ResponseWriter, } } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + var request NoContentHeadersRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx, request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(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)) + } +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { var request RequiredJSONBodyRequestObject @@ -1693,26 +1766,27 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/gorilla/server.go b/internal/test/strict-server/gorilla/server.go index 2cb801e035..3d3890d982 100644 --- a/internal/test/strict-server/gorilla/server.go +++ b/internal/test/strict-server/gorilla/server.go @@ -98,6 +98,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 5d2dce3b6c..649d39e2e2 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -38,6 +38,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx iris.Context) + // (POST /no-content-headers) + NoContentHeaders(ctx iris.Context) + // (POST /required-json-body) RequiredJSONBody(ctx iris.Context) @@ -104,6 +107,13 @@ func (w *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(ctx iris.Contex w.Handler.MultipleRequestAndResponseTypes(ctx) } +// NoContentHeaders converts iris context to params. +func (w *ServerInterfaceWrapper) NoContentHeaders(ctx iris.Context) { + + // Invoke the callback with all the unmarshaled arguments + w.Handler.NoContentHeaders(ctx) +} + // RequiredJSONBody converts iris context to params. func (w *ServerInterfaceWrapper) RequiredJSONBody(ctx iris.Context) { @@ -259,6 +269,7 @@ func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, o router.Post(options.BaseURL+"/multipart", wrapper.MultipartExample) router.Post(options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample) router.Post(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + router.Post(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders) router.Post(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) router.Post(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) router.Get(options.BaseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters) @@ -471,6 +482,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(ctx iris.Context) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(ctx iris.Context) error { + if response.Headers.NullableHeader != nil { + ctx.ResponseWriter().Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + ctx.ResponseWriter().Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + ctx.StatusCode(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -891,6 +929,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1116,6 +1157,33 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx iris.Context) { } } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(ctx iris.Context) { + var request NoContentHeadersRequestObject + + handler := func(ctx iris.Context, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx, request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.StopWithError(http.StatusBadRequest, err) + return + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(ctx); err != nil { + ctx.StopWithError(http.StatusBadRequest, err) + return + } + } else if response != nil { + ctx.Writef("Unexpected response type: %T", response) + return + } +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(ctx iris.Context) { var request RequiredJSONBodyRequestObject @@ -1465,26 +1533,27 @@ func (sh *strictHandler) UnionExample(ctx iris.Context) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/iris/server.go b/internal/test/strict-server/iris/server.go index f87df99759..12b000d733 100644 --- a/internal/test/strict-server/iris/server.go +++ b/internal/test/strict-server/iris/server.go @@ -121,6 +121,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index adca621779..b3c693a5ba 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -40,6 +40,9 @@ type ServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(w http.ResponseWriter, r *http.Request) + // (POST /no-content-headers) + NoContentHeaders(w http.ResponseWriter, r *http.Request) + // (POST /required-json-body) RequiredJSONBody(w http.ResponseWriter, r *http.Request) @@ -136,6 +139,20 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(w http.Respon handler.ServeHTTP(w, r) } +// NoContentHeaders operation middleware +func (siw *ServerInterfaceWrapper) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.NoContentHeaders(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // RequiredJSONBody operation middleware func (siw *ServerInterfaceWrapper) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { @@ -462,6 +479,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multipart", wrapper.MultipartExample) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/required-text-body", wrapper.RequiredTextBody) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters) @@ -689,6 +707,33 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA return nil } +type NoContentHeadersRequestObject struct { +} + +type NoContentHeadersResponseObject interface { + VisitNoContentHeadersResponse(w http.ResponseWriter) error +} + +type NoContentHeaders204ResponseHeaders struct { + NullableHeader *string + OptionalHeader *string +} + +type NoContentHeaders204Response struct { + Headers NoContentHeaders204ResponseHeaders +} + +func (response NoContentHeaders204Response) VisitNoContentHeadersResponse(w http.ResponseWriter) error { + if response.Headers.NullableHeader != nil { + w.Header().Set("nullable-header", fmt.Sprint(*response.Headers.NullableHeader)) + } + if response.Headers.OptionalHeader != nil { + w.Header().Set("optional-header", fmt.Sprint(*response.Headers.OptionalHeader)) + } + w.WriteHeader(204) + return nil +} + type RequiredJSONBodyRequestObject struct { Body *RequiredJSONBodyJSONRequestBody } @@ -1139,6 +1184,9 @@ type StrictServerInterface interface { // (POST /multiple) MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error) + // (POST /no-content-headers) + NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) + // (POST /required-json-body) RequiredJSONBody(ctx context.Context, request RequiredJSONBodyRequestObject) (RequiredJSONBodyResponseObject, error) @@ -1369,6 +1417,30 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(w http.ResponseWriter, } } +// NoContentHeaders operation middleware +func (sh *strictHandler) NoContentHeaders(w http.ResponseWriter, r *http.Request) { + var request NoContentHeadersRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.NoContentHeaders(ctx, request.(NoContentHeadersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "NoContentHeaders") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { + if err := validResponse.VisitNoContentHeadersResponse(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)) + } +} + // RequiredJSONBody operation middleware func (sh *strictHandler) RequiredJSONBody(w http.ResponseWriter, r *http.Request) { var request RequiredJSONBodyRequestObject @@ -1688,26 +1760,27 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xZzXLbNhB+FQzaUwqatuOTbo0nk7Zp645snzo+QMRKQgICCLAUrdHo3TsgQP3SjpRK", - "lieTm0TuH75vd7kAZrQwpTUaNHram1EH3hrtofkz4MLBlwo8hn8CfOGkRWk07dF3XPTTuzmjDirPBwpa", - "9SBfGI2gG1VurZIFD6r5Jx/0Z9QXYyh5+PWzgyHt0Z/yZSh5fOtzeOSlVUDn8znbiODmI2V0DFyAa6KN", - "Py/iKr5U0oGgPXQVsBVfOLVAe9Sjk3pEg9GodrmTmtQII3AhmqCaggwCbZy9GbXOWHAoI4YTriro9pye", - "mMEnKDCuUOqh2cb62mjkUnsi5HAIDjSSBC4JNjzxlbXGIQgymJLgoUDiwU3AUUZRYgiM3q4+JylgTxmd", - "gPPR0cXZ+dl54NNY0NxK2qNvm0eMWo7jZkELAq3pyos/bm/+JtITXqEpOcqCKzUlJXd+zBUIIjWaEGJV", - "oD+jjSfXJMbvImm/T1AympLvnRHTYyRUk7cr6X55fv5CeTtn9Co667KxCCpfKcDGzJBXqgPze/1Zm1oT", - "cM64tLK8rBRKyx2ucrWO9l+tyC6QL+zlQ+PKTHDkR0L9UJ5ODXzmQHEM7eSrBPSj5H48rJg/Kgv/x89J", - "OUj9uLNP3Y5N7cnY1AQNEcAVqSWOSau40WClJpx4qUcKSBsU6yRTQfos/qpFP63lLtg4ej9ja1Yes7qu", - "s6aAKqdAF0Z8G4WMypKPILd6tK4ebHOkPTqYYkjZ7Q/cgQqZUYRHzK3icgOYTZcv1NJ/IH2wwo7l2g5e", - "WWAkG6T66C7cVF4kSIVBo9VlxBtSSh+qNL70Y1MpQbiq+dTH/rA9cfSTepg8msI8+tjBNubM73sMWVAb", - "Mus01N7BI36V2j0Sf1/6Xrqm9qeo2ROIbGSyzzCtjROZ5Y6XgOB8PgtxzoOtEXSY/GchSQquyQCI5iUI", - "wocIjnwwJJn0HfxEvx/MxyiyNNVsOBZ/ev/OaACv2YRQRoMD2ov4sT02ew/HpapFM26FszVXTyV8Emmh", - "czD0YSDp4rgDv+ipvyJxmi3T87m5dTjwEkkdmHx68A4tYZdh+4CDx2vvAlV8+DRmSWsX2L5xjtkBxYkU", - "YPLSXu1p+WSgeguFHEoQWVpFFmN7qiVcG104wPUNSPgYaoNkYYwMpgTHQCICzfexBlJWHonl3hOJTRdR", - "Mp4VCdhqHvfLyK6jp7tlO32O1TdH4vTNqRi9Or/YX+XtkfNmbSPxRD32/3wfZfY9MTvYjmXP/dbh/J6o", - "nGuJ42zlyLm7hH+LAstvegFyEiYiLYgDrJwGQSaSt8egW7WZDCxp7ZqFYhjLaag9/t5nIGLP2rqkzx6B", - "P3zHB7Snu1hgVFdKNQNkYmVtSe3L1tK2W9Msg6tO9a7u/DJVU2n53LXBfXhN0kS/+aWSRr/SSwGuEJzm", - "KCfwy2FOk7atGA03w6buN9hjO3p4eH2XZ8fOujmj8Z4rNszKqdDVEG0vz+P92Jmv+WgE7kyanFsZUPov", - "AAD//ysZ4qQMHQAA", + "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", + "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", + "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", + "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", + "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", + "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", + "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", + "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", + "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", + "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", + "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", + "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", + "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", + "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", + "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", + "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", + "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", + "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", + "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", + "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", + "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/test/strict-server/stdhttp/server.go b/internal/test/strict-server/stdhttp/server.go index 4f39f939cc..3d24a5d272 100644 --- a/internal/test/strict-server/stdhttp/server.go +++ b/internal/test/strict-server/stdhttp/server.go @@ -124,6 +124,10 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil } +func (s StrictServer) NoContentHeaders(ctx context.Context, request NoContentHeadersRequestObject) (NoContentHeadersResponseObject, error) { + return NoContentHeaders204Response{}, nil +} + func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/stdhttp/std_strict_test.go b/internal/test/strict-server/stdhttp/std_strict_test.go index 40d362a54a..4c1e76e9ac 100644 --- a/internal/test/strict-server/stdhttp/std_strict_test.go +++ b/internal/test/strict-server/stdhttp/std_strict_test.go @@ -196,6 +196,12 @@ func testImpl(t *testing.T, handler http.Handler) { assert.Equal(t, header1, rr.Header().Get("header1")) assert.Equal(t, header2, rr.Header().Get("header2")) }) + t.Run("NoContentHeadersOmitUnset", func(t *testing.T) { + rr := testutil.NewRequest().Post("/no-content-headers").GoWithHTTPHandler(t, handler).Recorder + assert.Equal(t, http.StatusNoContent, rr.Code) + assert.Empty(t, rr.Header().Values("optional-header"), "optional-header should be omitted when the response field is nil") + assert.Empty(t, rr.Header().Values("nullable-header"), "nullable-header should be omitted when the response field is unspecified") + }) t.Run("UnspecifiedContentType", func(t *testing.T) { data := []byte("image data") contentType := "image/jpeg" diff --git a/internal/test/strict-server/strict-schema.yaml b/internal/test/strict-server/strict-schema.yaml index ba1a2ffab3..fd5f07feda 100644 --- a/internal/test/strict-server/strict-schema.yaml +++ b/internal/test/strict-server/strict-schema.yaml @@ -215,6 +215,22 @@ paths: $ref: "#/components/responses/badrequest" default: description: Unknown error + /no-content-headers: + post: + operationId: NoContentHeaders + description: No-content (204) response with optional and nullable response headers — exercises that unset headers are omitted from the response + responses: + 204: + description: No Content + headers: + optional-header: + required: false + schema: + type: string + nullable-header: + schema: + type: string + nullable: true /reusable-responses: post: operationId: ReusableResponses diff --git a/internal/test/strict-server/strict_test.go b/internal/test/strict-server/strict_test.go index 03cade9cc9..49a6abe25a 100644 --- a/internal/test/strict-server/strict_test.go +++ b/internal/test/strict-server/strict_test.go @@ -228,6 +228,12 @@ func testImpl(t *testing.T, handler http.Handler) { assert.Equal(t, header1, rr.Header().Get("header1")) assert.Equal(t, header2, rr.Header().Get("header2")) }) + t.Run("NoContentHeadersOmitUnset", func(t *testing.T) { + rr := testutil.NewRequest().Post("/no-content-headers").GoWithHTTPHandler(t, handler).Recorder + assert.Equal(t, http.StatusNoContent, rr.Code) + assert.Empty(t, rr.Header().Values("optional-header"), "optional-header should be omitted when the response field is nil") + assert.Empty(t, rr.Header().Values("nullable-header"), "nullable-header should be omitted when the response field is unspecified") + }) t.Run("UnspecifiedContentType", func(t *testing.T) { data := []byte("image data") contentType := "image/jpeg" diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index 9ff692e814..baad4ab4e5 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -173,7 +173,17 @@ {{end -}} func (response {{$opid}}{{$statusCode}}Response) Visit{{$opid}}Response(ctx *fiber.Ctx) error { {{range $headers -}} - ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} ctx.Status({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) return nil diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 25e7455081..39fbc98855 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -212,7 +212,17 @@ {{end -}} func (response {{$opid}}{{$statusCode}}Response) Visit{{$opid}}Response(w http.ResponseWriter) error { {{range $headers -}} - w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + w.Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} w.WriteHeader({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) return nil diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 0594e5993a..5d9b5965c0 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -174,7 +174,17 @@ {{end -}} func (response {{$opid}}{{$statusCode}}Response) Visit{{$opid}}Response(ctx iris.Context) error { {{range $headers -}} - ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{if .IsNullable -}} + if response.Headers.{{.GoName}}.IsSpecified() { + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet())) + } + {{else if .IsOptional -}} + if response.Headers.{{.GoName}} != nil { + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}})) + } + {{else -}} + ctx.ResponseWriter().Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) + {{end -}} {{end -}} ctx.StatusCode({{if $fixedStatusCode}}{{$statusCode}}{{else}}response.StatusCode{{end}}) return nil From 036a54b7619b0c1da0e20b960bcd80428dec7980 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 30 Apr 2026 07:12:24 -0700 Subject: [PATCH 57/62] per-operation middleware in Echo (#2353) Closes: #518 Add a RegisterHandlersWithOptions to both Echo backends, which takes a BaseUrl and a map of OperationMiddlewares, keyed by spec OperationId. Only Echo supports registering per-op middleware, so this change is only for Echo. --- .../echo-v5/api/petstore-server.gen.go | 33 ++++-- .../echo/api/petstore-server.gen.go | 41 +++++-- .../test/any_of/codegen/inline/openapi.gen.go | 27 ++++- .../any_of/codegen/ref_schema/openapi.gen.go | 27 ++++- internal/test/filter/operations/server.gen.go | 29 ++++- internal/test/filter/tags/server.gen.go | 29 ++++- internal/test/issues/issue-1180/issue.gen.go | 27 ++++- .../test/issues/issue-1182/pkg1/pkg1.gen.go | 27 ++++- .../test/issues/issue-1182/pkg2/pkg2.gen.go | 25 ++++- .../test/issues/issue-1189/issue1189.gen.go | 27 ++++- .../test/issues/issue-1397/issue1397.gen.go | 27 ++++- .../issue-1529/strict-echo/issue1529.gen.go | 27 ++++- internal/test/issues/issue-312/issue.gen.go | 29 ++++- internal/test/issues/issue-518/config.yaml | 6 + internal/test/issues/issue-518/doc.go | 3 + .../test/issues/issue-518/issue518.gen.go | 106 ++++++++++++++++++ .../test/issues/issue-518/issue518_test.go | 106 ++++++++++++++++++ internal/test/issues/issue-518/spec.yaml | 26 +++++ internal/test/issues/issue-52/issue.gen.go | 27 ++++- .../issue-grab_import_names/issue.gen.go | 27 ++++- .../issue-illegal_enum_names/issue.gen.go | 27 ++++- .../test/parameters/echo/gen/server.gen.go | 79 ++++++++----- internal/test/parameters/echov5/server.gen.go | 79 ++++++++----- internal/test/schemas/schemas.gen.go | 45 +++++--- .../test/strict-server/echo/server.gen.go | 55 ++++++--- pkg/codegen/operations.go | 29 ++++- pkg/codegen/templates/echo/echo-register.tmpl | 27 ++++- .../templates/echo/v5/echo-register.tmpl | 27 ++++- 28 files changed, 864 insertions(+), 180 deletions(-) create mode 100644 internal/test/issues/issue-518/config.yaml create mode 100644 internal/test/issues/issue-518/doc.go create mode 100644 internal/test/issues/issue-518/issue518.gen.go create mode 100644 internal/test/issues/issue-518/issue518_test.go create mode 100644 internal/test/issues/issue-518/spec.yaml diff --git a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go index ac4b6f5270..7dc2404777 100644 --- a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go +++ b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go @@ -121,23 +121,42 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/pets", wrapper.FindPets) - router.POST(baseURL+"/pets", wrapper.AddPet) - router.DELETE(baseURL+"/pets/:id", wrapper.DeletePet) - router.GET(baseURL+"/pets/:id", wrapper.FindPetByID) + router.GET(options.BaseURL+"/pets", wrapper.FindPets, options.OperationMiddlewares["findPets"]...) + router.POST(options.BaseURL+"/pets", wrapper.AddPet, options.OperationMiddlewares["addPet"]...) + router.DELETE(options.BaseURL+"/pets/:id", wrapper.DeletePet, options.OperationMiddlewares["deletePet"]...) + router.GET(options.BaseURL+"/pets/:id", wrapper.FindPetByID, options.OperationMiddlewares["findPetByID"]...) } diff --git a/examples/petstore-expanded/echo/api/petstore-server.gen.go b/examples/petstore-expanded/echo/api/petstore-server.gen.go index 8767c17a14..8565fafd5e 100644 --- a/examples/petstore-expanded/echo/api/petstore-server.gen.go +++ b/examples/petstore-expanded/echo/api/petstore-server.gen.go @@ -48,14 +48,14 @@ func (w *ServerInterfaceWrapper) FindPets(ctx echo.Context) error { var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", ctx.QueryParams(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", ctx.QueryParams(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tags: %s", err)) } // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err)) } @@ -80,7 +80,7 @@ func (w *ServerInterfaceWrapper) DeletePet(ctx echo.Context) error { // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) } @@ -96,7 +96,7 @@ func (w *ServerInterfaceWrapper) FindPetByID(ctx echo.Context) error { // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err)) } @@ -121,23 +121,42 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/pets", wrapper.FindPets) - router.POST(baseURL+"/pets", wrapper.AddPet) - router.DELETE(baseURL+"/pets/:id", wrapper.DeletePet) - router.GET(baseURL+"/pets/:id", wrapper.FindPetByID) + router.GET(options.BaseURL+"/pets", wrapper.FindPets, options.OperationMiddlewares["findPets"]...) + router.POST(options.BaseURL+"/pets", wrapper.AddPet, options.OperationMiddlewares["addPet"]...) + router.DELETE(options.BaseURL+"/pets/:id", wrapper.DeletePet, options.OperationMiddlewares["deletePet"]...) + router.GET(options.BaseURL+"/pets/:id", wrapper.FindPetByID, options.OperationMiddlewares["findPetByID"]...) } diff --git a/internal/test/any_of/codegen/inline/openapi.gen.go b/internal/test/any_of/codegen/inline/openapi.gen.go index fff0ef0f89..c9eeb406b3 100644 --- a/internal/test/any_of/codegen/inline/openapi.gen.go +++ b/internal/test/any_of/codegen/inline/openapi.gen.go @@ -412,19 +412,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/pets", wrapper.GetPets) + router.GET(options.BaseURL+"/pets", wrapper.GetPets, options.OperationMiddlewares["getPets"]...) } diff --git a/internal/test/any_of/codegen/ref_schema/openapi.gen.go b/internal/test/any_of/codegen/ref_schema/openapi.gen.go index 0aa30cd67f..f8dcee8ce4 100644 --- a/internal/test/any_of/codegen/ref_schema/openapi.gen.go +++ b/internal/test/any_of/codegen/ref_schema/openapi.gen.go @@ -413,19 +413,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/pets", wrapper.GetPets) + router.GET(options.BaseURL+"/pets", wrapper.GetPets, options.OperationMiddlewares["getPets"]...) } diff --git a/internal/test/filter/operations/server.gen.go b/internal/test/filter/operations/server.gen.go index 49fc69b5e5..157483ed85 100644 --- a/internal/test/filter/operations/server.gen.go +++ b/internal/test/filter/operations/server.gen.go @@ -55,20 +55,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/included1", wrapper.IncludedOperation1) - router.GET(baseURL+"/included2", wrapper.IncludedOperation2) + router.GET(options.BaseURL+"/included1", wrapper.IncludedOperation1, options.OperationMiddlewares["included-operation1"]...) + router.GET(options.BaseURL+"/included2", wrapper.IncludedOperation2, options.OperationMiddlewares["included-operation2"]...) } diff --git a/internal/test/filter/tags/server.gen.go b/internal/test/filter/tags/server.gen.go index 8137c0f39c..59f4dd8b03 100644 --- a/internal/test/filter/tags/server.gen.go +++ b/internal/test/filter/tags/server.gen.go @@ -55,20 +55,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/included1", wrapper.IncludedOperation1) - router.GET(baseURL+"/included2", wrapper.IncludedOperation2) + router.GET(options.BaseURL+"/included1", wrapper.IncludedOperation1, options.OperationMiddlewares["included-operation1"]...) + router.GET(options.BaseURL+"/included2", wrapper.IncludedOperation2, options.OperationMiddlewares["included-operation2"]...) } diff --git a/internal/test/issues/issue-1180/issue.gen.go b/internal/test/issues/issue-1180/issue.gen.go index 37499ca5cc..ffab4accf7 100644 --- a/internal/test/issues/issue-1180/issue.gen.go +++ b/internal/test/issues/issue-1180/issue.gen.go @@ -287,20 +287,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) + router.GET(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive, options.OperationMiddlewares["getSimplePrimitive"]...) } diff --git a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go index 5baac42d25..13cce371bf 100644 --- a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go @@ -273,20 +273,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/test", wrapper.TestGet) + router.GET(options.BaseURL+"/test", wrapper.TestGet, options.OperationMiddlewares["TestGet"]...) } diff --git a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go index df4e45e12d..906298efc5 100644 --- a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go @@ -162,14 +162,33 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { } diff --git a/internal/test/issues/issue-1189/issue1189.gen.go b/internal/test/issues/issue-1189/issue1189.gen.go index e06d16c824..c13992c9b5 100644 --- a/internal/test/issues/issue-1189/issue1189.gen.go +++ b/internal/test/issues/issue-1189/issue1189.gen.go @@ -495,20 +495,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/test", wrapper.Test) + router.GET(options.BaseURL+"/test", wrapper.Test, options.OperationMiddlewares["Test"]...) } diff --git a/internal/test/issues/issue-1397/issue1397.gen.go b/internal/test/issues/issue-1397/issue1397.gen.go index 81bfad13c2..8d51c9d305 100644 --- a/internal/test/issues/issue-1397/issue1397.gen.go +++ b/internal/test/issues/issue-1397/issue1397.gen.go @@ -358,20 +358,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/test", wrapper.Test) + router.GET(options.BaseURL+"/test", wrapper.Test, options.OperationMiddlewares["test"]...) } diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index 5356f847bb..7e5a0c7929 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -303,20 +303,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/test", wrapper.Test) + router.GET(options.BaseURL+"/test", wrapper.Test, options.OperationMiddlewares["test"]...) } diff --git a/internal/test/issues/issue-312/issue.gen.go b/internal/test/issues/issue-312/issue.gen.go index 07102f000b..e149b26d44 100644 --- a/internal/test/issues/issue-312/issue.gen.go +++ b/internal/test/issues/issue-312/issue.gen.go @@ -490,21 +490,40 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/pets/:petId", wrapper.GetPet) - router.POST(baseURL+"/pets:validate", wrapper.ValidatePets) + router.GET(options.BaseURL+"/pets/:petId", wrapper.GetPet, options.OperationMiddlewares["getPet"]...) + router.POST(options.BaseURL+"/pets:validate", wrapper.ValidatePets, options.OperationMiddlewares["validatePets"]...) } diff --git a/internal/test/issues/issue-518/config.yaml b/internal/test/issues/issue-518/config.yaml new file mode 100644 index 0000000000..5b1cf72492 --- /dev/null +++ b/internal/test/issues/issue-518/config.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: issue518 +generate: + echo-server: true + models: true +output: issue518.gen.go diff --git a/internal/test/issues/issue-518/doc.go b/internal/test/issues/issue-518/doc.go new file mode 100644 index 0000000000..5276da3dd7 --- /dev/null +++ b/internal/test/issues/issue-518/doc.go @@ -0,0 +1,3 @@ +package issue518 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/issues/issue-518/issue518.gen.go b/internal/test/issues/issue-518/issue518.gen.go new file mode 100644 index 0000000000..79f72d1430 --- /dev/null +++ b/internal/test/issues/issue-518/issue518.gen.go @@ -0,0 +1,106 @@ +// Package issue518 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 issue518 + +import ( + "github.com/labstack/echo/v4" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /alpha) + GetAlpha(ctx echo.Context) error + + // (GET /beta) + GetBeta(ctx echo.Context) error + + // (GET /gamma) + GetGamma(ctx echo.Context) error +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +// GetAlpha converts echo context to params. +func (w *ServerInterfaceWrapper) GetAlpha(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetAlpha(ctx) + return err +} + +// GetBeta converts echo context to params. +func (w *ServerInterfaceWrapper) GetBeta(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetBeta(ctx) + return err +} + +// GetGamma converts echo context to params. +func (w *ServerInterfaceWrapper) GetGamma(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetGamma(ctx) + return err +} + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route +} + +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) +} + +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.GET(options.BaseURL+"/alpha", wrapper.GetAlpha, options.OperationMiddlewares["get-alpha"]...) + router.GET(options.BaseURL+"/beta", wrapper.GetBeta, options.OperationMiddlewares["get-beta"]...) + router.GET(options.BaseURL+"/gamma", wrapper.GetGamma, options.OperationMiddlewares["GetGamma"]...) + +} diff --git a/internal/test/issues/issue-518/issue518_test.go b/internal/test/issues/issue-518/issue518_test.go new file mode 100644 index 0000000000..af58469dab --- /dev/null +++ b/internal/test/issues/issue-518/issue518_test.go @@ -0,0 +1,106 @@ +package issue518 + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/labstack/echo/v4" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type stubServer struct{} + +func (stubServer) GetAlpha(ctx echo.Context) error { return ctx.NoContent(http.StatusOK) } +func (stubServer) GetBeta(ctx echo.Context) error { return ctx.NoContent(http.StatusOK) } +func (stubServer) GetGamma(ctx echo.Context) error { return ctx.NoContent(http.StatusOK) } + +// recordingMiddleware appends a tag to the slice it closes over each time it +// runs. Lets the test assert which routes the middleware ran on. +func recordingMiddleware(record *[]string, tag string) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + *record = append(*record, tag) + return next(c) + } + } +} + +func TestRegisterHandlersWithOptions_PerOperationMiddleware(t *testing.T) { + var calls []string + + e := echo.New() + RegisterHandlersWithOptions(e, stubServer{}, RegisterHandlersOptions{ + OperationMiddlewares: map[string][]echo.MiddlewareFunc{ + // Spec-form key (kebab-case), proving the map is NOT keyed on the + // normalized Go identifier "GetAlpha". + "get-alpha": {recordingMiddleware(&calls, "alpha-mw")}, + }, + }) + + srv := httptest.NewServer(e) + defer srv.Close() + + for _, path := range []string{"/alpha", "/beta", "/gamma"} { + resp, err := http.Get(srv.URL + path) + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + require.Equal(t, http.StatusOK, resp.StatusCode, "path %s", path) + } + + // Middleware fires only on /alpha, not /beta or /gamma. + assert.Equal(t, []string{"alpha-mw"}, calls) +} + +func TestRegisterHandlersWithOptions_FallbackKeyForGeneratedOperationId(t *testing.T) { + var calls []string + + e := echo.New() + // /gamma has no spec operationId, so the codegen generated one. Per the + // MiddlewareKey() fallback, the map key in this case is the normalized + // OperationId — copy whatever the wrapper method is named. + RegisterHandlersWithOptions(e, stubServer{}, RegisterHandlersOptions{ + OperationMiddlewares: map[string][]echo.MiddlewareFunc{ + "GetGamma": {recordingMiddleware(&calls, "gamma-mw")}, + }, + }) + + srv := httptest.NewServer(e) + defer srv.Close() + + resp, err := http.Get(srv.URL + "/gamma") + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + require.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, []string{"gamma-mw"}, calls) +} + +func TestRegisterHandlers_BackwardsCompatible(t *testing.T) { + // Existing call sites using RegisterHandlers / RegisterHandlersWithBaseURL + // must keep working — they delegate to RegisterHandlersWithOptions with no + // per-operation middleware. + e := echo.New() + RegisterHandlers(e, stubServer{}) + + srv := httptest.NewServer(e) + defer srv.Close() + + resp, err := http.Get(srv.URL + "/alpha") + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestRegisterHandlersWithBaseURL_BackwardsCompatible(t *testing.T) { + e := echo.New() + RegisterHandlersWithBaseURL(e, stubServer{}, "/api") + + srv := httptest.NewServer(e) + defer srv.Close() + + resp, err := http.Get(srv.URL + "/api/alpha") + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + assert.Equal(t, http.StatusOK, resp.StatusCode) +} diff --git a/internal/test/issues/issue-518/spec.yaml b/internal/test/issues/issue-518/spec.yaml new file mode 100644 index 0000000000..2bc84308b6 --- /dev/null +++ b/internal/test/issues/issue-518/spec.yaml @@ -0,0 +1,26 @@ +openapi: 3.0.0 +info: + title: issue-518 per-operation middleware regression + version: '1.0' +paths: + /alpha: + get: + # Deliberately kebab-case to exercise that OperationMiddlewares is keyed + # on the spec's raw operationId, not the normalized Go identifier. + operationId: get-alpha + responses: + '200': + description: OK + /beta: + get: + operationId: get-beta + responses: + '200': + description: OK + /gamma: + # No operationId on this one — codegen generates a default. The map key + # falls back to the normalized OperationId in that case. + get: + responses: + '200': + description: OK diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go index d79ef78059..07fd1b0a14 100644 --- a/internal/test/issues/issue-52/issue.gen.go +++ b/internal/test/issues/issue-52/issue.gen.go @@ -298,20 +298,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/example", wrapper.ExampleGet) + router.GET(options.BaseURL+"/example", wrapper.ExampleGet, options.OperationMiddlewares["exampleGet"]...) } diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go index 08af8f82ed..32cf049063 100644 --- a/internal/test/issues/issue-grab_import_names/issue.gen.go +++ b/internal/test/issues/issue-grab_import_names/issue.gen.go @@ -355,20 +355,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/foo", wrapper.GetFoo) + router.GET(options.BaseURL+"/foo", wrapper.GetFoo, options.OperationMiddlewares["GetFoo"]...) } diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go index 277dc53e3f..11a39afe9e 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go +++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go @@ -329,20 +329,39 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/foo", wrapper.GetFoo) + router.GET(options.BaseURL+"/foo", wrapper.GetFoo, options.OperationMiddlewares["GetFoo"]...) } diff --git a/internal/test/parameters/echo/gen/server.gen.go b/internal/test/parameters/echo/gen/server.gen.go index c3c6d36d8f..ee44e88832 100644 --- a/internal/test/parameters/echo/gen/server.gen.go +++ b/internal/test/parameters/echo/gen/server.gen.go @@ -834,46 +834,65 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/contentObject/:param", wrapper.GetContentObject) - router.GET(baseURL+"/cookie", wrapper.GetCookie) - router.GET(baseURL+"/enums", wrapper.EnumParams) - router.GET(baseURL+"/header", wrapper.GetHeader) - router.GET(baseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) - router.GET(baseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) - router.GET(baseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) - router.GET(baseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) - router.GET(baseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) - router.GET(baseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) - router.GET(baseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) - router.GET(baseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) - router.GET(baseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) - router.GET(baseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) - router.GET(baseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) - router.GET(baseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) - router.GET(baseURL+"/passThrough/:param", wrapper.GetPassThrough) - router.GET(baseURL+"/queryDeepObject", wrapper.GetDeepObject) - router.GET(baseURL+"/queryDelimited", wrapper.GetQueryDelimited) - router.GET(baseURL+"/queryForm", wrapper.GetQueryForm) - router.GET(baseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) - router.GET(baseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) - router.GET(baseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) - router.GET(baseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) - router.GET(baseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) - router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) - router.GET(baseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + router.GET(options.BaseURL+"/contentObject/:param", wrapper.GetContentObject, options.OperationMiddlewares["getContentObject"]...) + router.GET(options.BaseURL+"/cookie", wrapper.GetCookie, options.OperationMiddlewares["getCookie"]...) + router.GET(options.BaseURL+"/enums", wrapper.EnumParams, options.OperationMiddlewares["enumParams"]...) + router.GET(options.BaseURL+"/header", wrapper.GetHeader, options.OperationMiddlewares["getHeader"]...) + router.GET(options.BaseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray, options.OperationMiddlewares["getLabelExplodeArray"]...) + router.GET(options.BaseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject, options.OperationMiddlewares["getLabelExplodeObject"]...) + router.GET(options.BaseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive, options.OperationMiddlewares["getLabelExplodePrimitive"]...) + router.GET(options.BaseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray, options.OperationMiddlewares["getLabelNoExplodeArray"]...) + router.GET(options.BaseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject, options.OperationMiddlewares["getLabelNoExplodeObject"]...) + router.GET(options.BaseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive, options.OperationMiddlewares["getLabelPrimitive"]...) + router.GET(options.BaseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray, options.OperationMiddlewares["getMatrixExplodeArray"]...) + router.GET(options.BaseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject, options.OperationMiddlewares["getMatrixExplodeObject"]...) + router.GET(options.BaseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive, options.OperationMiddlewares["getMatrixExplodePrimitive"]...) + router.GET(options.BaseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray, options.OperationMiddlewares["getMatrixNoExplodeArray"]...) + router.GET(options.BaseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject, options.OperationMiddlewares["getMatrixNoExplodeObject"]...) + router.GET(options.BaseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive, options.OperationMiddlewares["getMatrixPrimitive"]...) + router.GET(options.BaseURL+"/passThrough/:param", wrapper.GetPassThrough, options.OperationMiddlewares["getPassThrough"]...) + router.GET(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject, options.OperationMiddlewares["getDeepObject"]...) + router.GET(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited, options.OperationMiddlewares["getQueryDelimited"]...) + router.GET(options.BaseURL+"/queryForm", wrapper.GetQueryForm, options.OperationMiddlewares["getQueryForm"]...) + router.GET(options.BaseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray, options.OperationMiddlewares["getSimpleExplodeArray"]...) + router.GET(options.BaseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject, options.OperationMiddlewares["getSimpleExplodeObject"]...) + router.GET(options.BaseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive, options.OperationMiddlewares["getSimpleExplodePrimitive"]...) + router.GET(options.BaseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray, options.OperationMiddlewares["getSimpleNoExplodeArray"]...) + router.GET(options.BaseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject, options.OperationMiddlewares["getSimpleNoExplodeObject"]...) + router.GET(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive, options.OperationMiddlewares["getSimplePrimitive"]...) + router.GET(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber, options.OperationMiddlewares["getStartingWithNumber"]...) } diff --git a/internal/test/parameters/echov5/server.gen.go b/internal/test/parameters/echov5/server.gen.go index 748ae76ad1..46a5ed2ad7 100644 --- a/internal/test/parameters/echov5/server.gen.go +++ b/internal/test/parameters/echov5/server.gen.go @@ -834,46 +834,65 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/contentObject/:param", wrapper.GetContentObject) - router.GET(baseURL+"/cookie", wrapper.GetCookie) - router.GET(baseURL+"/enums", wrapper.EnumParams) - router.GET(baseURL+"/header", wrapper.GetHeader) - router.GET(baseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray) - router.GET(baseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject) - router.GET(baseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive) - router.GET(baseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray) - router.GET(baseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject) - router.GET(baseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive) - router.GET(baseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray) - router.GET(baseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject) - router.GET(baseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive) - router.GET(baseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray) - router.GET(baseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject) - router.GET(baseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive) - router.GET(baseURL+"/passThrough/:param", wrapper.GetPassThrough) - router.GET(baseURL+"/queryDeepObject", wrapper.GetDeepObject) - router.GET(baseURL+"/queryDelimited", wrapper.GetQueryDelimited) - router.GET(baseURL+"/queryForm", wrapper.GetQueryForm) - router.GET(baseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray) - router.GET(baseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject) - router.GET(baseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive) - router.GET(baseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray) - router.GET(baseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject) - router.GET(baseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive) - router.GET(baseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) + router.GET(options.BaseURL+"/contentObject/:param", wrapper.GetContentObject, options.OperationMiddlewares["getContentObject"]...) + router.GET(options.BaseURL+"/cookie", wrapper.GetCookie, options.OperationMiddlewares["getCookie"]...) + router.GET(options.BaseURL+"/enums", wrapper.EnumParams, options.OperationMiddlewares["enumParams"]...) + router.GET(options.BaseURL+"/header", wrapper.GetHeader, options.OperationMiddlewares["getHeader"]...) + router.GET(options.BaseURL+"/labelExplodeArray/:param", wrapper.GetLabelExplodeArray, options.OperationMiddlewares["getLabelExplodeArray"]...) + router.GET(options.BaseURL+"/labelExplodeObject/:param", wrapper.GetLabelExplodeObject, options.OperationMiddlewares["getLabelExplodeObject"]...) + router.GET(options.BaseURL+"/labelExplodePrimitive/:param", wrapper.GetLabelExplodePrimitive, options.OperationMiddlewares["getLabelExplodePrimitive"]...) + router.GET(options.BaseURL+"/labelNoExplodeArray/:param", wrapper.GetLabelNoExplodeArray, options.OperationMiddlewares["getLabelNoExplodeArray"]...) + router.GET(options.BaseURL+"/labelNoExplodeObject/:param", wrapper.GetLabelNoExplodeObject, options.OperationMiddlewares["getLabelNoExplodeObject"]...) + router.GET(options.BaseURL+"/labelPrimitive/:param", wrapper.GetLabelPrimitive, options.OperationMiddlewares["getLabelPrimitive"]...) + router.GET(options.BaseURL+"/matrixExplodeArray/:id", wrapper.GetMatrixExplodeArray, options.OperationMiddlewares["getMatrixExplodeArray"]...) + router.GET(options.BaseURL+"/matrixExplodeObject/:id", wrapper.GetMatrixExplodeObject, options.OperationMiddlewares["getMatrixExplodeObject"]...) + router.GET(options.BaseURL+"/matrixExplodePrimitive/:id", wrapper.GetMatrixExplodePrimitive, options.OperationMiddlewares["getMatrixExplodePrimitive"]...) + router.GET(options.BaseURL+"/matrixNoExplodeArray/:id", wrapper.GetMatrixNoExplodeArray, options.OperationMiddlewares["getMatrixNoExplodeArray"]...) + router.GET(options.BaseURL+"/matrixNoExplodeObject/:id", wrapper.GetMatrixNoExplodeObject, options.OperationMiddlewares["getMatrixNoExplodeObject"]...) + router.GET(options.BaseURL+"/matrixPrimitive/:id", wrapper.GetMatrixPrimitive, options.OperationMiddlewares["getMatrixPrimitive"]...) + router.GET(options.BaseURL+"/passThrough/:param", wrapper.GetPassThrough, options.OperationMiddlewares["getPassThrough"]...) + router.GET(options.BaseURL+"/queryDeepObject", wrapper.GetDeepObject, options.OperationMiddlewares["getDeepObject"]...) + router.GET(options.BaseURL+"/queryDelimited", wrapper.GetQueryDelimited, options.OperationMiddlewares["getQueryDelimited"]...) + router.GET(options.BaseURL+"/queryForm", wrapper.GetQueryForm, options.OperationMiddlewares["getQueryForm"]...) + router.GET(options.BaseURL+"/simpleExplodeArray/:param", wrapper.GetSimpleExplodeArray, options.OperationMiddlewares["getSimpleExplodeArray"]...) + router.GET(options.BaseURL+"/simpleExplodeObject/:param", wrapper.GetSimpleExplodeObject, options.OperationMiddlewares["getSimpleExplodeObject"]...) + router.GET(options.BaseURL+"/simpleExplodePrimitive/:param", wrapper.GetSimpleExplodePrimitive, options.OperationMiddlewares["getSimpleExplodePrimitive"]...) + router.GET(options.BaseURL+"/simpleNoExplodeArray/:param", wrapper.GetSimpleNoExplodeArray, options.OperationMiddlewares["getSimpleNoExplodeArray"]...) + router.GET(options.BaseURL+"/simpleNoExplodeObject/:param", wrapper.GetSimpleNoExplodeObject, options.OperationMiddlewares["getSimpleNoExplodeObject"]...) + router.GET(options.BaseURL+"/simplePrimitive/:param", wrapper.GetSimplePrimitive, options.OperationMiddlewares["getSimplePrimitive"]...) + router.GET(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber, options.OperationMiddlewares["getStartingWithNumber"]...) } diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index 828428a84a..d47eea4e87 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -1657,29 +1657,48 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/ensure-everything-is-referenced", wrapper.EnsureEverythingIsReferenced) - router.GET(baseURL+"/issues/1051", wrapper.Issue1051) - router.GET(baseURL+"/issues/127", wrapper.Issue127) - router.GET(baseURL+"/issues/185", wrapper.Issue185) - router.GET(baseURL+"/issues/209/$:str", wrapper.Issue209) - router.GET(baseURL+"/issues/30/:fallthrough", wrapper.Issue30) - router.GET(baseURL+"/issues/375", wrapper.GetIssues375) - router.GET(baseURL+"/issues/41/:1param", wrapper.Issue41) - router.GET(baseURL+"/issues/9", wrapper.Issue9) - router.GET(baseURL+"/issues/975", wrapper.Issue975) + router.GET(options.BaseURL+"/ensure-everything-is-referenced", wrapper.EnsureEverythingIsReferenced, options.OperationMiddlewares["ensureEverythingIsReferenced"]...) + router.GET(options.BaseURL+"/issues/1051", wrapper.Issue1051, options.OperationMiddlewares["Issue1051"]...) + router.GET(options.BaseURL+"/issues/127", wrapper.Issue127, options.OperationMiddlewares["Issue127"]...) + router.GET(options.BaseURL+"/issues/185", wrapper.Issue185, options.OperationMiddlewares["Issue185"]...) + router.GET(options.BaseURL+"/issues/209/$:str", wrapper.Issue209, options.OperationMiddlewares["Issue209"]...) + router.GET(options.BaseURL+"/issues/30/:fallthrough", wrapper.Issue30, options.OperationMiddlewares["Issue30"]...) + router.GET(options.BaseURL+"/issues/375", wrapper.GetIssues375, options.OperationMiddlewares["GetIssues375"]...) + router.GET(options.BaseURL+"/issues/41/:1param", wrapper.Issue41, options.OperationMiddlewares["Issue41"]...) + router.GET(options.BaseURL+"/issues/9", wrapper.Issue9, options.OperationMiddlewares["Issue9"]...) + router.GET(options.BaseURL+"/issues/975", wrapper.Issue975, options.OperationMiddlewares["Issue975"]...) } diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index be6d0687fc..12172f8336 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -272,34 +272,53 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.POST(baseURL+"/json", wrapper.JSONExample) - router.POST(baseURL+"/multipart", wrapper.MultipartExample) - router.POST(baseURL+"/multipart-related", wrapper.MultipartRelatedExample) - router.POST(baseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes) - router.POST(baseURL+"/no-content-headers", wrapper.NoContentHeaders) - router.POST(baseURL+"/required-json-body", wrapper.RequiredJSONBody) - router.POST(baseURL+"/required-text-body", wrapper.RequiredTextBody) - router.GET(baseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters) - router.POST(baseURL+"/reusable-responses", wrapper.ReusableResponses) - router.POST(baseURL+"/text", wrapper.TextExample) - router.POST(baseURL+"/unknown", wrapper.UnknownExample) - router.POST(baseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType) - router.POST(baseURL+"/urlencoded", wrapper.URLEncodedExample) - router.POST(baseURL+"/with-headers", wrapper.HeadersExample) - router.POST(baseURL+"/with-union", wrapper.UnionExample) + router.POST(options.BaseURL+"/json", wrapper.JSONExample, options.OperationMiddlewares["JSONExample"]...) + router.POST(options.BaseURL+"/multipart", wrapper.MultipartExample, options.OperationMiddlewares["MultipartExample"]...) + router.POST(options.BaseURL+"/multipart-related", wrapper.MultipartRelatedExample, options.OperationMiddlewares["MultipartRelatedExample"]...) + router.POST(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes, options.OperationMiddlewares["MultipleRequestAndResponseTypes"]...) + router.POST(options.BaseURL+"/no-content-headers", wrapper.NoContentHeaders, options.OperationMiddlewares["NoContentHeaders"]...) + router.POST(options.BaseURL+"/required-json-body", wrapper.RequiredJSONBody, options.OperationMiddlewares["RequiredJSONBody"]...) + router.POST(options.BaseURL+"/required-text-body", wrapper.RequiredTextBody, options.OperationMiddlewares["RequiredTextBody"]...) + router.GET(options.BaseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters, options.OperationMiddlewares["ReservedGoKeywordParameters"]...) + router.POST(options.BaseURL+"/reusable-responses", wrapper.ReusableResponses, options.OperationMiddlewares["ReusableResponses"]...) + router.POST(options.BaseURL+"/text", wrapper.TextExample, options.OperationMiddlewares["TextExample"]...) + router.POST(options.BaseURL+"/unknown", wrapper.UnknownExample, options.OperationMiddlewares["UnknownExample"]...) + router.POST(options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType, options.OperationMiddlewares["UnspecifiedContentType"]...) + router.POST(options.BaseURL+"/urlencoded", wrapper.URLEncodedExample, options.OperationMiddlewares["URLEncodedExample"]...) + router.POST(options.BaseURL+"/with-headers", wrapper.HeadersExample, options.OperationMiddlewares["HeadersExample"]...) + router.POST(options.BaseURL+"/with-union", wrapper.UnionExample, options.OperationMiddlewares["UnionExample"]...) } diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index 4087d30fec..94b6911c71 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -313,6 +313,8 @@ func DescribeSecurityDefinition(securityRequirements openapi3.SecurityRequiremen type OperationDefinition struct { // OperationId is the `operationId` field from the OpenAPI Specification, after going through a `nameNormalizer`, and will be used to generate function names OperationId string + // SpecOperationId is the raw `operationId` value as it appears in the OpenAPI spec, before normalization to a Go identifier. Empty when the spec didn't supply one (in which case the codegen-generated ID is the only available identifier and is exposed via OperationId). + SpecOperationId string PathParams []ParameterDefinition // Parameters in the path, eg, /path/:param HeaderParams []ParameterDefinition // Parameters in HTTP headers @@ -342,6 +344,17 @@ func (o *OperationDefinition) HandlerName() string { return o.OperationId } +// MiddlewareKey returns the identifier to use as the key in per-operation +// middleware maps. The raw spec OperationId is preferred so map keys mirror +// the OpenAPI spec verbatim; falls back to the normalized OperationId when +// the spec didn't supply one. +func (o *OperationDefinition) MiddlewareKey() string { + if o.SpecOperationId != "" { + return o.SpecOperationId + } + return o.OperationId +} + // Params returns the list of all parameters except Path parameters. Path parameters // are handled differently from the rest, since they're mandatory. func (o *OperationDefinition) Params() []ParameterDefinition { @@ -757,6 +770,11 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { } // take a copy of operationId, so we don't modify the underlying spec operationId := op.OperationID + // Preserve the raw spec value (pre-normalization, pre-prefix, pre-alias-suffix) + // so templates that need to mirror the OpenAPI spec verbatim — e.g. echo's + // per-operation middleware map key — can do so without seeing the + // Go-identifier-friendly transformations applied below. + specOperationId := op.OperationID // We rely on OperationID to generate function names, it's required if operationId == "" { operationId, err = generateDefaultOperationID(opName, requestPath) @@ -831,11 +849,12 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) { ensureExternalRefsInResponseDefinitions(&responseDefinitions, pathItem.Ref) opDef := OperationDefinition{ - PathParams: pathParams, - HeaderParams: FilterParameterDefinitionByType(allParams, "header"), - QueryParams: FilterParameterDefinitionByType(allParams, "query"), - CookieParams: FilterParameterDefinitionByType(allParams, "cookie"), - OperationId: nameNormalizer(operationId), + PathParams: pathParams, + HeaderParams: FilterParameterDefinitionByType(allParams, "header"), + QueryParams: FilterParameterDefinitionByType(allParams, "query"), + CookieParams: FilterParameterDefinitionByType(allParams, "cookie"), + OperationId: nameNormalizer(operationId), + SpecOperationId: specOperationId, // Replace newlines in summary. Summary: op.Summary, Method: opName, diff --git a/pkg/codegen/templates/echo/echo-register.tmpl b/pkg/codegen/templates/echo/echo-register.tmpl index dcfeb54f18..def0917e31 100644 --- a/pkg/codegen/templates/echo/echo-register.tmpl +++ b/pkg/codegen/templates/echo/echo-register.tmpl @@ -15,19 +15,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { {{if .}} wrapper := ServerInterfaceWrapper{ Handler: si, } {{end}} -{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}) +{{range .}}router.{{.Method}}(options.BaseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}, options.OperationMiddlewares["{{.MiddlewareKey}}"]...) {{end}} } diff --git a/pkg/codegen/templates/echo/v5/echo-register.tmpl b/pkg/codegen/templates/echo/v5/echo-register.tmpl index bd0e968b0f..d311fefbe2 100644 --- a/pkg/codegen/templates/echo/v5/echo-register.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-register.tmpl @@ -15,19 +15,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) echo.RouteInfo } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { {{if .}} wrapper := ServerInterfaceWrapper{ Handler: si, } {{end}} -{{range .}}router.{{.Method}}(baseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}) +{{range .}}router.{{.Method}}(options.BaseURL + "{{.Path | swaggerUriToEchoUri}}", wrapper.{{.HandlerName}}, options.OperationMiddlewares["{{.MiddlewareKey}}"]...) {{end}} } From 9643421365d811bdfa09098204388a1682b2b95d Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 30 Apr 2026 09:36:27 -0700 Subject: [PATCH 58/62] fix example codegen (#2354) * fix example codegen aae687ce8fe987714a5c6ba1e18a704dc4503209 broke example codegen, since the "generate" directory caused the "make generate" rule not to run, since it already existed. It needs to be .PHONY. I'll refactor examples a bit later. * Pin to HEAD pseudo-version --- examples/Makefile | 1 + .../authenticated-api/echo/api/api.gen.go | 49 ++++++++-- examples/client/client.gen.go | 20 +++- examples/clienttypenameclash/client.gen.go | 10 +- .../custom-client-type.gen.go | 10 +- examples/extensions/xenumnames/gen.go | 36 +++++++ examples/go.mod | 2 + .../multiplepackages/admin/server.gen.go | 3 +- .../import-mapping/samepackage/server.gen.go | 18 ++-- examples/minimal-server/echo/api/ping.gen.go | 27 +++++- examples/minimal-server/fiber/api/ping.gen.go | 26 ++++- .../minimal-server/gorillamux/api/ping.gen.go | 2 +- .../stdhttp-go-tool/api/ping.gen.go | 6 +- .../echo/api/api.gen.go | 27 +++++- examples/overlay/api/ping.gen.go | 2 +- .../petstore-expanded/chi/api/petstore.gen.go | 26 +++-- .../fiber/api/petstore-server.gen.go | 75 +++++++++++++-- .../gin/api/petstore-server.gen.go | 11 ++- .../gorilla/api/petstore.gen.go | 34 +++++-- .../iris/api/petstore-server.gen.go | 11 ++- .../petstore-expanded/petstore-client.gen.go | 56 +++++++++-- .../strict/api/petstore-server.gen.go | 94 ++++++++++++++----- .../streaming/client/sse/streaming.gen.go | 8 ++ .../streaming/stdhttp/sse/streaming.gen.go | 5 +- 24 files changed, 453 insertions(+), 106 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 5ec0edd058..41d1778de8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -4,6 +4,7 @@ lint: lint-ci: $(GOBIN)/golangci-lint run ./... --output.text.path=stdout --timeout=5m +.PHONY: generate generate: go generate ./... diff --git a/examples/authenticated-api/echo/api/api.gen.go b/examples/authenticated-api/echo/api/api.gen.go index 1dc357519f..9cada0501d 100644 --- a/examples/authenticated-api/echo/api/api.gen.go +++ b/examples/authenticated-api/echo/api/api.gen.go @@ -187,7 +187,7 @@ func NewListThingsRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -225,7 +225,7 @@ func NewAddThingRequestWithBody(server string, contentType string, body io.Reade return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -309,6 +309,14 @@ func (r ListThingsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r ListThingsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type AddThingResponse struct { Body []byte HTTPResponse *http.Response @@ -331,6 +339,14 @@ func (r AddThingResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r AddThingResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // ListThingsWithResponse request returning *ListThingsResponse func (c *ClientWithResponses) ListThingsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ListThingsResponse, error) { rsp, err := c.ListThings(ctx, reqEditors...) @@ -461,21 +477,40 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/things", wrapper.ListThings) - router.POST(baseURL+"/things", wrapper.AddThing) + router.GET(options.BaseURL+"/things", wrapper.ListThings, options.OperationMiddlewares["listThings"]...) + router.POST(options.BaseURL+"/things", wrapper.AddThing, options.OperationMiddlewares["addThing"]...) } diff --git a/examples/client/client.gen.go b/examples/client/client.gen.go index 8ef6b78564..786d8c0b10 100644 --- a/examples/client/client.gen.go +++ b/examples/client/client.gen.go @@ -141,7 +141,7 @@ func NewGetClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func NewUpdateClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodPut, queryURL.String(), nil) if err != nil { return nil, err } @@ -248,6 +248,14 @@ func (r GetClientResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetClientResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type UpdateClientResponse struct { Body []byte HTTPResponse *http.Response @@ -272,6 +280,14 @@ func (r UpdateClientResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UpdateClientResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetClientWithResponse request returning *GetClientResponse func (c *ClientWithResponses) GetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error) { rsp, err := c.GetClient(ctx, reqEditors...) diff --git a/examples/clienttypenameclash/client.gen.go b/examples/clienttypenameclash/client.gen.go index 219a2a0d4d..4ed74d1777 100644 --- a/examples/clienttypenameclash/client.gen.go +++ b/examples/clienttypenameclash/client.gen.go @@ -126,7 +126,7 @@ func NewUpdateClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodPut, queryURL.String(), nil) if err != nil { return nil, err } @@ -203,6 +203,14 @@ func (r UpdateClientResp) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r UpdateClientResp) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // UpdateClientWithResponse request returning *UpdateClientResp func (c *ClientWithResponses) UpdateClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*UpdateClientResp, error) { rsp, err := c.UpdateClient(ctx, reqEditors...) diff --git a/examples/custom-client-type/custom-client-type.gen.go b/examples/custom-client-type/custom-client-type.gen.go index 6dd2ef0195..27f63d8185 100644 --- a/examples/custom-client-type/custom-client-type.gen.go +++ b/examples/custom-client-type/custom-client-type.gen.go @@ -126,7 +126,7 @@ func NewGetClientRequest(server string) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -203,6 +203,14 @@ func (r GetClientResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetClientResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetClientWithResponse request returning *GetClientResponse func (c *ClientWithResponses) GetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error) { rsp, err := c.GetClient(ctx, reqEditors...) diff --git a/examples/extensions/xenumnames/gen.go b/examples/extensions/xenumnames/gen.go index 73ebfa656c..7d9596d6b4 100644 --- a/examples/extensions/xenumnames/gen.go +++ b/examples/extensions/xenumnames/gen.go @@ -9,18 +9,54 @@ const ( EXP ClientType = "EXP" ) +// Valid indicates whether the value is a known member of the ClientType enum. +func (e ClientType) Valid() bool { + switch e { + case ACT: + return true + case EXP: + return true + default: + return false + } +} + // Defines values for ClientTypeWithNamesExtension. const ( ClientTypeWithNamesExtensionActive ClientTypeWithNamesExtension = "ACT" ClientTypeWithNamesExtensionExpired ClientTypeWithNamesExtension = "EXP" ) +// Valid indicates whether the value is a known member of the ClientTypeWithNamesExtension enum. +func (e ClientTypeWithNamesExtension) Valid() bool { + switch e { + case ClientTypeWithNamesExtensionActive: + return true + case ClientTypeWithNamesExtensionExpired: + return true + default: + return false + } +} + // Defines values for ClientTypeWithVarNamesExtension. const ( ClientTypeWithVarNamesExtensionActive ClientTypeWithVarNamesExtension = "ACT" ClientTypeWithVarNamesExtensionExpired ClientTypeWithVarNamesExtension = "EXP" ) +// Valid indicates whether the value is a known member of the ClientTypeWithVarNamesExtension enum. +func (e ClientTypeWithVarNamesExtension) Valid() bool { + switch e { + case ClientTypeWithVarNamesExtensionActive: + return true + case ClientTypeWithVarNamesExtensionExpired: + return true + default: + return false + } +} + // ClientType defines model for ClientType. type ClientType string diff --git a/examples/go.mod b/examples/go.mod index 547b7aaf10..cb225c3da4 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -126,3 +126,5 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen diff --git a/examples/import-mapping/multiplepackages/admin/server.gen.go b/examples/import-mapping/multiplepackages/admin/server.gen.go index 36e33e4c4c..3235142110 100644 --- a/examples/import-mapping/multiplepackages/admin/server.gen.go +++ b/examples/import-mapping/multiplepackages/admin/server.gen.go @@ -42,11 +42,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetUserById(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id openapi_types.UUID - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return diff --git a/examples/import-mapping/samepackage/server.gen.go b/examples/import-mapping/samepackage/server.gen.go index bd9445262b..22710b98d8 100644 --- a/examples/import-mapping/samepackage/server.gen.go +++ b/examples/import-mapping/samepackage/server.gen.go @@ -4,6 +4,7 @@ package samepackage import ( + "bytes" "context" "encoding/json" "fmt" @@ -11,7 +12,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" openapi_types "github.com/oapi-codegen/runtime/types" ) @@ -45,11 +45,12 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) GetUserById(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id openapi_types.UUID - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -197,10 +198,15 @@ type GetUserByIdResponseObject interface { type GetUserById200JSONResponse User func (response GetUserById200JSONResponse) VisitGetUserByIdResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. @@ -210,8 +216,8 @@ type StrictServerInterface interface { GetUserById(ctx context.Context, request GetUserByIdRequestObject) (GetUserByIdResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/examples/minimal-server/echo/api/ping.gen.go b/examples/minimal-server/echo/api/ping.gen.go index bd78f8f2ad..e376e807d2 100644 --- a/examples/minimal-server/echo/api/ping.gen.go +++ b/examples/minimal-server/echo/api/ping.gen.go @@ -48,19 +48,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/ping", wrapper.GetPing) + router.GET(options.BaseURL+"/ping", wrapper.GetPing, options.OperationMiddlewares["GetPing"]...) } diff --git a/examples/minimal-server/fiber/api/ping.gen.go b/examples/minimal-server/fiber/api/ping.gen.go index a21e6fa956..b926f841bb 100644 --- a/examples/minimal-server/fiber/api/ping.gen.go +++ b/examples/minimal-server/fiber/api/ping.gen.go @@ -21,21 +21,36 @@ type ServerInterface interface { // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { - Handler ServerInterface + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error // GetPing operation middleware func (siw *ServerInterfaceWrapper) GetPing(c *fiber.Ctx) error { - return siw.Handler.GetPing(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.GetPing(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FiberServerOptions provides options for the Fiber server. type FiberServerOptions struct { - BaseURL string - Middlewares []MiddlewareFunc + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -46,7 +61,8 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { wrapper := ServerInterfaceWrapper{ - Handler: si, + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/examples/minimal-server/gorillamux/api/ping.gen.go b/examples/minimal-server/gorillamux/api/ping.gen.go index 9445d02b53..82ec6ebb5d 100644 --- a/examples/minimal-server/gorillamux/api/ping.gen.go +++ b/examples/minimal-server/gorillamux/api/ping.gen.go @@ -158,7 +158,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods("GET") + r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods(http.MethodGet) return r } diff --git a/examples/minimal-server/stdhttp-go-tool/api/ping.gen.go b/examples/minimal-server/stdhttp-go-tool/api/ping.gen.go index 794f8d817f..0d4ab7751a 100644 --- a/examples/minimal-server/stdhttp-go-tool/api/ping.gen.go +++ b/examples/minimal-server/stdhttp-go-tool/api/ping.gen.go @@ -119,10 +119,10 @@ func Handler(si ServerInterface) http.Handler { return HandlerWithOptions(si, StdHTTPServerOptions{}) } -// ServeMux is an abstraction of http.ServeMux. +// ServeMux is an abstraction of [http.ServeMux]. type ServeMux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) - ServeHTTP(w http.ResponseWriter, r *http.Request) + http.Handler } type StdHTTPServerOptions struct { @@ -165,7 +165,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - m.HandleFunc("GET "+options.BaseURL+"/ping", wrapper.GetPing) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/ping", wrapper.GetPing) return m } diff --git a/examples/no-vcs-version-override/echo/api/api.gen.go b/examples/no-vcs-version-override/echo/api/api.gen.go index e95391fd13..0d70421505 100644 --- a/examples/no-vcs-version-override/echo/api/api.gen.go +++ b/examples/no-vcs-version-override/echo/api/api.gen.go @@ -43,19 +43,38 @@ type EchoRouter interface { TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route } +// RegisterHandlersOptions configures RegisterHandlersWithOptions. +type RegisterHandlersOptions struct { + // BaseURL is prepended to every registered path so the API can be served + // under a prefix. + BaseURL string + // OperationMiddlewares lets the caller attach per-operation middleware at + // registration time. The map key is the OpenAPI `operationId` value as it + // appears in the spec (the raw, un-normalized form). Operations that have + // no entry are registered with no extra middleware. A nil map disables + // per-operation middleware entirely. + OperationMiddlewares map[string][]echo.MiddlewareFunc +} + // RegisterHandlers adds each server route to the EchoRouter. func RegisterHandlers(router EchoRouter, si ServerInterface) { - RegisterHandlersWithBaseURL(router, si, "") + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{}) } -// Registers handlers, and prepends BaseURL to the paths, so that the paths -// can be served under a prefix. +// RegisterHandlersWithBaseURL registers handlers and prepends BaseURL to the +// paths so the API can be served under a prefix. func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + RegisterHandlersWithOptions(router, si, RegisterHandlersOptions{BaseURL: baseURL}) +} + +// RegisterHandlersWithOptions registers handlers using the supplied options, +// including any per-operation middleware. +func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options RegisterHandlersOptions) { wrapper := ServerInterfaceWrapper{ Handler: si, } - router.GET(baseURL+"/nothing", wrapper.GetNothing) + router.GET(options.BaseURL+"/nothing", wrapper.GetNothing, options.OperationMiddlewares["getNothing"]...) } diff --git a/examples/overlay/api/ping.gen.go b/examples/overlay/api/ping.gen.go index d36bdd55b3..757cd1c6b4 100644 --- a/examples/overlay/api/ping.gen.go +++ b/examples/overlay/api/ping.gen.go @@ -165,7 +165,7 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods("GET") + r.HandleFunc(options.BaseURL+"/ping", wrapper.GetPing).Methods(http.MethodGet) return r } diff --git a/examples/petstore-expanded/chi/api/petstore.gen.go b/examples/petstore-expanded/chi/api/petstore.gen.go index 88b246f37b..f599568124 100644 --- a/examples/petstore-expanded/chi/api/petstore.gen.go +++ b/examples/petstore-expanded/chi/api/petstore.gen.go @@ -7,6 +7,7 @@ import ( "bytes" "compress/gzip" "encoding/base64" + "errors" "fmt" "net/http" "net/url" @@ -117,23 +118,34 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", r.URL.Query(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", r.URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "tags"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + } return } // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", r.URL.Query(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", r.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "limit"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + } return } @@ -166,11 +178,12 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -191,11 +204,12 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return diff --git a/examples/petstore-expanded/fiber/api/petstore-server.gen.go b/examples/petstore-expanded/fiber/api/petstore-server.gen.go index a5c583ef06..c8f2b20b48 100644 --- a/examples/petstore-expanded/fiber/api/petstore-server.gen.go +++ b/examples/petstore-expanded/fiber/api/petstore-server.gen.go @@ -35,15 +35,18 @@ type ServerInterface interface { // ServerInterfaceWrapper converts contexts to parameters. type ServerInterfaceWrapper struct { - Handler ServerInterface + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc } type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c *fiber.Ctx, next fiber.Handler) error // FindPets operation middleware func (siw *ServerInterfaceWrapper) FindPets(c *fiber.Ctx) error { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams @@ -68,51 +71,102 @@ func (siw *ServerInterfaceWrapper) FindPets(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter limit: %w", err).Error()) } - return siw.Handler.FindPets(c, params) + handler := func(c *fiber.Ctx) error { + return siw.Handler.FindPets(c, params) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // AddPet operation middleware func (siw *ServerInterfaceWrapper) AddPet(c *fiber.Ctx) error { - return siw.Handler.AddPet(c) + handler := func(c *fiber.Ctx) error { + return siw.Handler.AddPet(c) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // DeletePet operation middleware func (siw *ServerInterfaceWrapper) DeletePet(c *fiber.Ctx) error { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "integer", Format: "int64"}) + err = runtime.BindStyledParameterWithOptions("simple", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) } - return siw.Handler.DeletePet(c, id) + handler := func(c *fiber.Ctx) error { + return siw.Handler.DeletePet(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FindPetByID operation middleware func (siw *ServerInterfaceWrapper) FindPetByID(c *fiber.Ctx) error { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true, Type: "integer", Format: "int64"}) + err = runtime.BindStyledParameterWithOptions("simple", "id", c.Params("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter id: %w", err).Error()) } - return siw.Handler.FindPetByID(c, id) + handler := func(c *fiber.Ctx) error { + return siw.Handler.FindPetByID(c, id) + } + + for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- { + m := siw.HandlerMiddlewares[i] + next := handler + handler = func(c *fiber.Ctx) error { + return m(c, next) + } + } + + return handler(c) } // FiberServerOptions provides options for the Fiber server. type FiberServerOptions struct { - BaseURL string - Middlewares []MiddlewareFunc + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc } // RegisterHandlers creates http.Handler with routing matching OpenAPI spec. @@ -123,7 +177,8 @@ func RegisterHandlers(router fiber.Router, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { wrapper := ServerInterfaceWrapper{ - Handler: si, + Handler: si, + HandlerMiddlewares: options.HandlerMiddlewares, } for _, m := range options.Middlewares { diff --git a/examples/petstore-expanded/gin/api/petstore-server.gen.go b/examples/petstore-expanded/gin/api/petstore-server.gen.go index 02499fcc18..52ce7a8087 100644 --- a/examples/petstore-expanded/gin/api/petstore-server.gen.go +++ b/examples/petstore-expanded/gin/api/petstore-server.gen.go @@ -47,13 +47,14 @@ type MiddlewareFunc func(c *gin.Context) func (siw *ServerInterfaceWrapper) FindPets(c *gin.Context) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", c.Request.URL.Query(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", c.Request.URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter tags: %w", err), http.StatusBadRequest) return @@ -61,7 +62,7 @@ func (siw *ServerInterfaceWrapper) FindPets(c *gin.Context) { // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", c.Request.URL.Query(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", c.Request.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter limit: %w", err), http.StatusBadRequest) return @@ -94,11 +95,12 @@ func (siw *ServerInterfaceWrapper) AddPet(c *gin.Context) { func (siw *ServerInterfaceWrapper) DeletePet(c *gin.Context) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) return @@ -118,11 +120,12 @@ func (siw *ServerInterfaceWrapper) DeletePet(c *gin.Context) { func (siw *ServerInterfaceWrapper) FindPetByID(c *gin.Context) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest) return diff --git a/examples/petstore-expanded/gorilla/api/petstore.gen.go b/examples/petstore-expanded/gorilla/api/petstore.gen.go index 0ccc7da0b5..dea4e55e54 100644 --- a/examples/petstore-expanded/gorilla/api/petstore.gen.go +++ b/examples/petstore-expanded/gorilla/api/petstore.gen.go @@ -7,6 +7,7 @@ import ( "bytes" "compress/gzip" "encoding/base64" + "errors" "fmt" "net/http" "net/url" @@ -89,23 +90,34 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", r.URL.Query(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", r.URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "tags"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + } return } // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", r.URL.Query(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", r.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "limit"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + } return } @@ -138,11 +150,12 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -163,11 +176,12 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", mux.Vars(r)["id"], &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -297,13 +311,13 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H ErrorHandlerFunc: options.ErrorHandlerFunc, } - r.HandleFunc(options.BaseURL+"/pets", wrapper.FindPets).Methods("GET") + r.HandleFunc(options.BaseURL+"/pets", wrapper.FindPets).Methods(http.MethodGet) - r.HandleFunc(options.BaseURL+"/pets", wrapper.AddPet).Methods("POST") + r.HandleFunc(options.BaseURL+"/pets", wrapper.AddPet).Methods(http.MethodPost) - r.HandleFunc(options.BaseURL+"/pets/{id}", wrapper.DeletePet).Methods("DELETE") + r.HandleFunc(options.BaseURL+"/pets/{id}", wrapper.DeletePet).Methods(http.MethodDelete) - r.HandleFunc(options.BaseURL+"/pets/{id}", wrapper.FindPetByID).Methods("GET") + r.HandleFunc(options.BaseURL+"/pets/{id}", wrapper.FindPetByID).Methods(http.MethodGet) return r } diff --git a/examples/petstore-expanded/iris/api/petstore-server.gen.go b/examples/petstore-expanded/iris/api/petstore-server.gen.go index a559c238d5..9f52757c5c 100644 --- a/examples/petstore-expanded/iris/api/petstore-server.gen.go +++ b/examples/petstore-expanded/iris/api/petstore-server.gen.go @@ -45,12 +45,13 @@ type MiddlewareFunc iris.Handler func (w *ServerInterfaceWrapper) FindPets(ctx iris.Context) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", ctx.Request().URL.Query(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", ctx.Request().URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.Writef("Invalid format for parameter tags: %s", err) @@ -59,7 +60,7 @@ func (w *ServerInterfaceWrapper) FindPets(ctx iris.Context) { // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", ctx.Request().URL.Query(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", ctx.Request().URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.Writef("Invalid format for parameter limit: %s", err) @@ -81,11 +82,12 @@ func (w *ServerInterfaceWrapper) AddPet(ctx iris.Context) { func (w *ServerInterfaceWrapper) DeletePet(ctx iris.Context) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.Writef("Invalid format for parameter id: %s", err) @@ -100,11 +102,12 @@ func (w *ServerInterfaceWrapper) DeletePet(ctx iris.Context) { func (w *ServerInterfaceWrapper) FindPetByID(ctx iris.Context) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Params().Get("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { ctx.StatusCode(http.StatusBadRequest) ctx.Writef("Invalid format for parameter id: %s", err) diff --git a/examples/petstore-expanded/petstore-client.gen.go b/examples/petstore-expanded/petstore-client.gen.go index aa35c93ca6..5b5d01d78b 100644 --- a/examples/petstore-expanded/petstore-client.gen.go +++ b/examples/petstore-expanded/petstore-client.gen.go @@ -236,20 +236,24 @@ func NewFindPetsRequest(server string, params *FindPetsParams) (*http.Request, e if params.Tags != nil { - if queryFragments, err := runtime.StyleParamWithLocation("form", true, "tags", runtime.ParamLocationQuery, *params.Tags); err != nil { + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "tags", *params.Tags, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "array", Format: ""}); err != nil { return nil, err } else { - rawQueryFragments = append(rawQueryFragments, queryFragments) + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } } } if params.Limit != nil { - if queryFragments, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "limit", *params.Limit, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "integer", Format: "int32"}); err != nil { return nil, err } else { - rawQueryFragments = append(rawQueryFragments, queryFragments) + for _, qp := range strings.Split(queryFrag, "&") { + rawQueryFragments = append(rawQueryFragments, qp) + } } } @@ -260,7 +264,7 @@ func NewFindPetsRequest(server string, params *FindPetsParams) (*http.Request, e queryURL.RawQuery = strings.Join(rawQueryFragments, "&") } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -298,7 +302,7 @@ func NewAddPetRequestWithBody(server string, contentType string, body io.Reader) return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest(http.MethodPost, queryURL.String(), body) if err != nil { return nil, err } @@ -314,7 +318,7 @@ func NewDeletePetRequest(server string, id int64) (*http.Request, error) { var pathParam0 string - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int64"}) if err != nil { return nil, err } @@ -334,7 +338,7 @@ func NewDeletePetRequest(server string, id int64) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("DELETE", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodDelete, queryURL.String(), nil) if err != nil { return nil, err } @@ -348,7 +352,7 @@ func NewFindPetByIDRequest(server string, id int64) (*http.Request, error) { var pathParam0 string - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id) + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "integer", Format: "int64"}) if err != nil { return nil, err } @@ -368,7 +372,7 @@ func NewFindPetByIDRequest(server string, id int64) (*http.Request, error) { return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest(http.MethodGet, queryURL.String(), nil) if err != nil { return nil, err } @@ -457,6 +461,14 @@ func (r FindPetsResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r FindPetsResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type AddPetResponse struct { Body []byte HTTPResponse *http.Response @@ -480,6 +492,14 @@ func (r AddPetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r AddPetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type DeletePetResponse struct { Body []byte HTTPResponse *http.Response @@ -502,6 +522,14 @@ func (r DeletePetResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r DeletePetResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + type FindPetByIDResponse struct { Body []byte HTTPResponse *http.Response @@ -525,6 +553,14 @@ func (r FindPetByIDResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r FindPetByIDResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // FindPetsWithResponse request returning *FindPetsResponse func (c *ClientWithResponses) FindPetsWithResponse(ctx context.Context, params *FindPetsParams, reqEditors ...RequestEditorFn) (*FindPetsResponse, error) { rsp, err := c.FindPets(ctx, params, reqEditors...) diff --git a/examples/petstore-expanded/strict/api/petstore-server.gen.go b/examples/petstore-expanded/strict/api/petstore-server.gen.go index f1ba3d6d44..4877d1d564 100644 --- a/examples/petstore-expanded/strict/api/petstore-server.gen.go +++ b/examples/petstore-expanded/strict/api/petstore-server.gen.go @@ -9,6 +9,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "net/http" "net/url" @@ -18,7 +19,6 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/go-chi/chi/v5" "github.com/oapi-codegen/runtime" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -78,23 +78,34 @@ type MiddlewareFunc func(http.Handler) http.Handler func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Request) { var err error + _ = err // Parameter object where we will unmarshal all parameters from the context var params FindPetsParams // ------------- Optional query parameter "tags" ------------- - err = runtime.BindQueryParameter("form", true, false, "tags", r.URL.Query(), ¶ms.Tags) + err = runtime.BindQueryParameterWithOptions("form", true, false, "tags", r.URL.Query(), ¶ms.Tags, runtime.BindQueryParameterOptions{Type: "array", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "tags"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "tags", Err: err}) + } return } // ------------- Optional query parameter "limit" ------------- - err = runtime.BindQueryParameter("form", true, false, "limit", r.URL.Query(), ¶ms.Limit) + err = runtime.BindQueryParameterWithOptions("form", true, false, "limit", r.URL.Query(), ¶ms.Limit, runtime.BindQueryParameterOptions{Type: "integer", Format: "int32"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "limit"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "limit", Err: err}) + } return } @@ -127,11 +138,12 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -152,11 +164,12 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Request) { var err error + _ = err // ------------- Path parameter "id" ------------- var id int64 - err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + err = runtime.BindStyledParameterWithOptions("simple", "id", chi.URLParam(r, "id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "integer", Format: "int64"}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "id", Err: err}) return @@ -313,10 +326,15 @@ type FindPetsResponseObject interface { type FindPets200JSONResponse []Pet func (response FindPets200JSONResponse) VisitFindPetsResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type FindPetsdefaultJSONResponse struct { @@ -325,10 +343,15 @@ type FindPetsdefaultJSONResponse struct { } func (response FindPetsdefaultJSONResponse) VisitFindPetsResponse(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") w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type AddPetRequestObject struct { @@ -342,10 +365,15 @@ type AddPetResponseObject interface { type AddPet200JSONResponse Pet func (response AddPet200JSONResponse) VisitAddPetResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type AddPetdefaultJSONResponse struct { @@ -354,10 +382,15 @@ type AddPetdefaultJSONResponse struct { } func (response AddPetdefaultJSONResponse) VisitAddPetResponse(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") w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type DeletePetRequestObject struct { @@ -382,10 +415,15 @@ type DeletePetdefaultJSONResponse struct { } func (response DeletePetdefaultJSONResponse) VisitDeletePetResponse(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") w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } type FindPetByIDRequestObject struct { @@ -399,10 +437,15 @@ type FindPetByIDResponseObject interface { type FindPetByID200JSONResponse Pet func (response FindPetByID200JSONResponse) VisitFindPetByIDResponse(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) - - return json.NewEncoder(w).Encode(response) + _, err := buf.WriteTo(w) + return err } type FindPetByIDdefaultJSONResponse struct { @@ -411,10 +454,15 @@ type FindPetByIDdefaultJSONResponse struct { } func (response FindPetByIDdefaultJSONResponse) VisitFindPetByIDResponse(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") w.WriteHeader(response.StatusCode) - - return json.NewEncoder(w).Encode(response.Body) + _, err := buf.WriteTo(w) + return err } // StrictServerInterface represents all server handlers. @@ -433,8 +481,8 @@ type StrictServerInterface interface { FindPetByID(ctx context.Context, request FindPetByIDRequestObject) (FindPetByIDResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) diff --git a/examples/streaming/client/sse/streaming.gen.go b/examples/streaming/client/sse/streaming.gen.go index 65a15573ff..d20b2063e3 100644 --- a/examples/streaming/client/sse/streaming.gen.go +++ b/examples/streaming/client/sse/streaming.gen.go @@ -196,6 +196,14 @@ func (r GetStreamResponse) StatusCode() int { return 0 } +// ContentType is a convenience method to retrieve the Content-Type value from the HTTP response headers +func (r GetStreamResponse) ContentType() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Header.Get("Content-Type") + } + return "" +} + // GetStreamWithResponse request returning *GetStreamResponse func (c *ClientWithResponses) GetStreamWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetStreamResponse, error) { rsp, err := c.GetStream(ctx, reqEditors...) diff --git a/examples/streaming/stdhttp/sse/streaming.gen.go b/examples/streaming/stdhttp/sse/streaming.gen.go index a619348ee0..94aa81e3e4 100644 --- a/examples/streaming/stdhttp/sse/streaming.gen.go +++ b/examples/streaming/stdhttp/sse/streaming.gen.go @@ -18,7 +18,6 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3" - strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" ) // ServerInterface represents all server handlers. @@ -233,8 +232,8 @@ type StrictServerInterface interface { GetStream(ctx context.Context, request GetStreamRequestObject) (GetStreamResponseObject, error) } -type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc -type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc +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) From 7517e092e25b19eeba293aa8e88a2b62626a5226 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 30 Apr 2026 11:54:15 -0700 Subject: [PATCH 59/62] respect output file path on gofmt failure (#2356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `imports.Process` rejected the generated source, `Generate()` discarded the code and stuffed a line-numbered dump of it into the returned error. The CLI then printed that error to stderr and never wrote the requested `-o` (or config `output:`) file, so users saw a huge stderr spew with no output file produced. Return the raw pre-format code from `Generate()` alongside the error, and have the CLI write it to the configured destination before exiting. The error message itself is now a single line referencing the failing source line; users can open the written file to inspect the broken code directly. `addLineNumbers` is dropped — it was only used by the removed in-error code dump. Closes: #2340 --- cmd/oapi-codegen/oapi-codegen.go | 32 +++++++++++++++++++------------- pkg/codegen/codegen.go | 25 ++++--------------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go index 604c0b3f0f..f540a6808a 100644 --- a/cmd/oapi-codegen/oapi-codegen.go +++ b/cmd/oapi-codegen/oapi-codegen.go @@ -320,21 +320,27 @@ func main() { opts.NoVCSVersionOverride = &noVCSVersionOverride } - code, err := codegen.Generate(swagger, opts.Configuration) - if err != nil { - errExit("error generating code: %s\n", err) + code, genErr := codegen.Generate(swagger, opts.Configuration) + + // Always emit any generated code to the requested destination, even when + // generation returned an error (e.g. the formatter rejected the output). + // Writing to the output file lets the user inspect the broken source + // directly instead of having it interleaved with stderr. + if code != "" { + if opts.OutputFile != "" { + if err := os.MkdirAll(filepath.Dir(opts.OutputFile), 0o755); err != nil { + errExit("error unable to create directory: %s\n", err) + } + if err := os.WriteFile(opts.OutputFile, []byte(code), 0o644); err != nil { + errExit("error writing generated code to file: %s\n", err) + } + } else { + fmt.Print(code) + } } - if opts.OutputFile != "" { - if err := os.MkdirAll(filepath.Dir(opts.OutputFile), 0o755); err != nil { - errExit("error unable to create directory: %s\n", err) - } - err = os.WriteFile(opts.OutputFile, []byte(code), 0o644) - if err != nil { - errExit("error writing generated code to file: %s\n", err) - } - } else { - fmt.Print(code) + if genErr != nil { + errExit("error generating code: %s\n", genErr) } } diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index fb588dcfa5..afb0f0e3db 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -517,34 +517,17 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { outBytes, err := imports.Process(opts.PackageName+".go", []byte(goCode), nil) if err != nil { - // if we don't get a line number errLine := -1 var scanErr scanner.ErrorList if errors.As(err, &scanErr) && scanErr.Len() > 0 { - // for now, only return the first error's information errLine = scanErr[0].Pos.Line } - return "", fmt.Errorf("error formatting Go code:\n%s\nerror was: %w", addLineNumbers(goCode, errLine), err) - } - return string(outBytes), nil -} - -func addLineNumbers(goCode string, lineWithError int) string { - var out []string - lines := strings.Split(goCode, "\n") - for i, line := range lines { - // lines for humans start at 1 - lineNumber := i + 1 - - errLine := " " - if lineNumber == lineWithError { - errLine = "❗" + if errLine > 0 { + return goCode, fmt.Errorf("error formatting Go code at line %d: %w", errLine, err) } - - out = append(out, fmt.Sprintf("%s%5d: %s", errLine, lineNumber, line)) + return goCode, fmt.Errorf("error formatting Go code: %w", err) } - - return strings.Join(out, "\n") + return string(outBytes), nil } func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []OperationDefinition, excludeSchemas []string) (string, error) { From fbc8e0dbb991a4d4c2928fce71400f338ece7228 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 30 Apr 2026 14:36:51 -0700 Subject: [PATCH 60/62] revert external-ref carve-out in strict-server response embedding (#2010) (#2357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #1387 added an `$isExternalRef` branch to the strict-{,fiber-,iris-} interface templates that strips the `Response` suffix when embedding an external response ref. That made external refs to a `components/responses/...` resolve to the bare schema name (`N400`) instead of the strict envelope (`N400JSONResponse`). The result: when spec A and spec B both generate strict-server and A $refs B's response component, A's local envelope embeds `N400JSONResponse` while A's external-ref envelope embeds `externalRef0.N400`. The two struct shapes are no longer identical, so cross-package response casts (the standard pattern for sharing error shapes across services) stop compiling — the regression filed as #2010. Investigation showed there is no smarter alternative: non-strict server modes emit no top-level type for `components/responses/...`, only `models: true` (gives the bare alias) and `strict-server: true` (gives the `JSONResponse` envelope, which is also the only form that carries a `Headers` field in the with-headers case) do. Changes: - Drop the `$isExternalRef` carve-out from the three strict-interface templates so external refs use the same `JSONResponse` embedding as internal refs. - Update `internal/test/issues/issue-removed-external-ref` golden output to match. - Update `internal/test/issues/issue-2113`'s common-package config to also generate `strict-server: true`. The fixture was relying on the PR #1387 behavior; under the new policy the destination of a strict-server external ref must also generate a strict server, so `StandardErrorJSONResponse` is in scope. - Add `internal/test/issues/issue-2010` regression fixture: two specs with strict-server, the second `$ref`s the first's `components/responses/400`, and the test exercises the cross-package cast that was broken. - README: note the cross-spec strict-server requirement under the strict-server section. The earlier two commits of #1387 are kept: the `Schema.IsExternalRef` helper, and the alias-vs-defined-type fix for content-schema external refs (which is a genuinely independent bug fix — methods can't be attached to non-local aliases). BREAKING CHANGE: external `$ref` to a `components/responses/...` from a strict-server target now requires the destination spec to also generate `strict-server: true`. This restores cross-package response casting that worked in v2.0.0 and earlier. Co-authored-by: Claude Opus 4.7 (1M context) --- README.md | 3 + .../test/issues/issue-2010/config.base.yaml | 10 + .../test/issues/issue-2010/config.other.yaml | 12 + internal/test/issues/issue-2010/doc.go | 10 + .../issues/issue-2010/gen/spec_base/.gitempty | 0 .../issue-2010/gen/spec_base/issue.gen.go | 271 ++++++++++++++++++ .../issue-2010/gen/spec_other/.gitempty | 0 .../issue-2010/gen/spec_other/issue.gen.go | 263 +++++++++++++++++ internal/test/issues/issue-2010/issue_test.go | 26 ++ .../test/issues/issue-2010/spec-base.yaml | 27 ++ .../test/issues/issue-2010/spec-other.yaml | 14 + .../test/issues/issue-2113/config.common.yaml | 1 + .../test/issues/issue-2113/gen/api/api.gen.go | 4 +- .../issue-2113/gen/common/common.gen.go | 2 + .../gen/spec_base/issue.gen.go | 4 +- .../strict/strict-fiber-interface.tmpl | 2 - .../templates/strict/strict-interface.tmpl | 2 - .../strict/strict-iris-interface.tmpl | 2 - 18 files changed, 645 insertions(+), 8 deletions(-) create mode 100644 internal/test/issues/issue-2010/config.base.yaml create mode 100644 internal/test/issues/issue-2010/config.other.yaml create mode 100644 internal/test/issues/issue-2010/doc.go create mode 100644 internal/test/issues/issue-2010/gen/spec_base/.gitempty create mode 100644 internal/test/issues/issue-2010/gen/spec_base/issue.gen.go create mode 100644 internal/test/issues/issue-2010/gen/spec_other/.gitempty create mode 100644 internal/test/issues/issue-2010/gen/spec_other/issue.gen.go create mode 100644 internal/test/issues/issue-2010/issue_test.go create mode 100644 internal/test/issues/issue-2010/spec-base.yaml create mode 100644 internal/test/issues/issue-2010/spec-other.yaml diff --git a/README.md b/README.md index bc9b8757e7..916a21dbcd 100644 --- a/README.md +++ b/README.md @@ -1534,6 +1534,9 @@ output: server.gen.go > [!NOTE] > This doesn't include [validation of incoming requests](#requestresponse-validation-middleware). +> [!IMPORTANT] +> When a strict-server spec uses `$ref` to point at a `components/responses/...` (or `components/requestBodies/...`) defined in another spec via `import-mapping`, the destination spec **must also be generated with `strict-server: true`**. The strict envelope embeds the `JSONResponse` type from the destination package; that type only exists when the destination generates a strict server. Without it the generated code will fail to compile with an "undefined" error. See [issue #2010](https://github.com/oapi-codegen/oapi-codegen/issues/2010). + ## Generating API clients As well as generating the server-side boilerplate, `oapi-codegen` can also generate API clients. diff --git a/internal/test/issues/issue-2010/config.base.yaml b/internal/test/issues/issue-2010/config.base.yaml new file mode 100644 index 0000000000..f42cfee5be --- /dev/null +++ b/internal/test/issues/issue-2010/config.base.yaml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=../../../../configuration-schema.json +package: spec_base +generate: + chi-server: true + strict-server: true + models: true +output: gen/spec_base/issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/issues/issue-2010/config.other.yaml b/internal/test/issues/issue-2010/config.other.yaml new file mode 100644 index 0000000000..17dde322c1 --- /dev/null +++ b/internal/test/issues/issue-2010/config.other.yaml @@ -0,0 +1,12 @@ +--- +# yaml-language-server: $schema=../../../../configuration-schema.json +package: spec_other +generate: + chi-server: true + strict-server: true + models: true +import-mapping: + ./spec-base.yaml: "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2010/gen/spec_base" +output: gen/spec_other/issue.gen.go +output-options: + skip-prune: true diff --git a/internal/test/issues/issue-2010/doc.go b/internal/test/issues/issue-2010/doc.go new file mode 100644 index 0000000000..6c6465877f --- /dev/null +++ b/internal/test/issues/issue-2010/doc.go @@ -0,0 +1,10 @@ +// Regression fixture for https://github.com/oapi-codegen/oapi-codegen/issues/2010. +// +// The base spec defines components/responses/400 with a JSON body. The "other" +// spec references that response via an external $ref. With strict-server +// enabled in both packages, the embedded response field name must agree across +// packages so cross-package response casts compile. +package issue_2010 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.base.yaml spec-base.yaml +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.other.yaml spec-other.yaml diff --git a/internal/test/issues/issue-2010/gen/spec_base/.gitempty b/internal/test/issues/issue-2010/gen/spec_base/.gitempty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/test/issues/issue-2010/gen/spec_base/issue.gen.go b/internal/test/issues/issue-2010/gen/spec_base/issue.gen.go new file mode 100644 index 0000000000..95fefde7d0 --- /dev/null +++ b/internal/test/issues/issue-2010/gen/spec_base/issue.gen.go @@ -0,0 +1,271 @@ +// Package spec_base 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 spec_base + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/go-chi/chi/v5" +) + +// N400 defines model for 400. +type N400 struct { + Message string `json:"message"` +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /example) + GetExample(w http.ResponseWriter, r *http.Request) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// (GET /example) +func (_ Unimplemented) GetExample(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// 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 + +// GetExample operation middleware +func (siw *ServerInterfaceWrapper) GetExample(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetExample(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, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + 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, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + 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, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/example", wrapper.GetExample) + }) + + return r +} + +type N400JSONResponse struct { + Message string `json:"message"` +} + +type GetExampleRequestObject struct { +} + +type GetExampleResponseObject interface { + VisitGetExampleResponse(w http.ResponseWriter) error +} + +type GetExample200Response struct { +} + +func (response GetExample200Response) VisitGetExampleResponse(w http.ResponseWriter) error { + w.WriteHeader(200) + return nil +} + +type GetExample400JSONResponse struct{ N400JSONResponse } + +func (response GetExample400JSONResponse) VisitGetExampleResponse(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(400) + _, err := buf.WriteTo(w) + return err +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (GET /example) + GetExample(ctx context.Context, request GetExampleRequestObject) (GetExampleResponseObject, 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 +} + +// GetExample operation middleware +func (sh *strictHandler) GetExample(w http.ResponseWriter, r *http.Request) { + var request GetExampleRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetExample(ctx, request.(GetExampleRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetExample") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetExampleResponseObject); ok { + if err := validResponse.VisitGetExampleResponse(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/issues/issue-2010/gen/spec_other/.gitempty b/internal/test/issues/issue-2010/gen/spec_other/.gitempty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/test/issues/issue-2010/gen/spec_other/issue.gen.go b/internal/test/issues/issue-2010/gen/spec_other/issue.gen.go new file mode 100644 index 0000000000..1c04f58afa --- /dev/null +++ b/internal/test/issues/issue-2010/gen/spec_other/issue.gen.go @@ -0,0 +1,263 @@ +// Package spec_other 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 spec_other + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/go-chi/chi/v5" + externalRef0 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2010/gen/spec_base" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /example) + GetOtherExample(w http.ResponseWriter, r *http.Request) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// (GET /example) +func (_ Unimplemented) GetOtherExample(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// 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 + +// GetOtherExample operation middleware +func (siw *ServerInterfaceWrapper) GetOtherExample(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetOtherExample(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, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + 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, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + 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, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/example", wrapper.GetOtherExample) + }) + + return r +} + +type GetOtherExampleRequestObject struct { +} + +type GetOtherExampleResponseObject interface { + VisitGetOtherExampleResponse(w http.ResponseWriter) error +} + +type GetOtherExample200Response struct { +} + +func (response GetOtherExample200Response) VisitGetOtherExampleResponse(w http.ResponseWriter) error { + w.WriteHeader(200) + return nil +} + +type GetOtherExample400JSONResponse struct{ externalRef0.N400JSONResponse } + +func (response GetOtherExample400JSONResponse) VisitGetOtherExampleResponse(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(400) + _, err := buf.WriteTo(w) + return err +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (GET /example) + GetOtherExample(ctx context.Context, request GetOtherExampleRequestObject) (GetOtherExampleResponseObject, 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 +} + +// GetOtherExample operation middleware +func (sh *strictHandler) GetOtherExample(w http.ResponseWriter, r *http.Request) { + var request GetOtherExampleRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetOtherExample(ctx, request.(GetOtherExampleRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetOtherExample") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetOtherExampleResponseObject); ok { + if err := validResponse.VisitGetOtherExampleResponse(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/issues/issue-2010/issue_test.go b/internal/test/issues/issue-2010/issue_test.go new file mode 100644 index 0000000000..c35741a98a --- /dev/null +++ b/internal/test/issues/issue-2010/issue_test.go @@ -0,0 +1,26 @@ +package issue_2010_test + +import ( + "testing" + + base "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2010/gen/spec_base" + other "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2010/gen/spec_other" +) + +// Cross-package cast that broke in 2.1.0+ when both specs generate +// strict-server. Compiling this file is the regression check: if the embedded +// field names diverge between the local and external strict envelopes, the +// conversion below fails to compile. +var _ = func(v base.GetExample400JSONResponse) other.GetOtherExample400JSONResponse { + return other.GetOtherExample400JSONResponse(v) +} + +func TestIssue2010ResponseCastAcrossPackages(t *testing.T) { + var a base.GetExampleResponseObject = base.GetExample400JSONResponse{} + switch v := a.(type) { + case base.GetExample400JSONResponse: + _ = other.GetOtherExample400JSONResponse(v) + default: + t.Fatalf("unexpected type %T", a) + } +} diff --git a/internal/test/issues/issue-2010/spec-base.yaml b/internal/test/issues/issue-2010/spec-base.yaml new file mode 100644 index 0000000000..931e4d4f90 --- /dev/null +++ b/internal/test/issues/issue-2010/spec-base.yaml @@ -0,0 +1,27 @@ +openapi: 3.0.1 +info: + description: An example schema + title: ExampleAPI + version: 1.0.0 +paths: + /example: + get: + operationId: getExample + responses: + '200': + description: OK + '400': + $ref: "#/components/responses/400" +components: + responses: + "400": + description: Bad Request + content: + application/json: + schema: + type: object + required: + - message + properties: + message: + type: string diff --git a/internal/test/issues/issue-2010/spec-other.yaml b/internal/test/issues/issue-2010/spec-other.yaml new file mode 100644 index 0000000000..f2ffd2305c --- /dev/null +++ b/internal/test/issues/issue-2010/spec-other.yaml @@ -0,0 +1,14 @@ +openapi: 3.0.1 +info: + description: Another example schema + title: OtherAPI + version: 1.0.0 +paths: + /example: + get: + operationId: getOtherExample + responses: + '200': + description: OK + '400': + $ref: "./spec-base.yaml#/components/responses/400" diff --git a/internal/test/issues/issue-2113/config.common.yaml b/internal/test/issues/issue-2113/config.common.yaml index f9803ed307..ce1b531f80 100644 --- a/internal/test/issues/issue-2113/config.common.yaml +++ b/internal/test/issues/issue-2113/config.common.yaml @@ -2,6 +2,7 @@ package: common generate: models: true + strict-server: true output: gen/common/common.gen.go output-options: skip-prune: true diff --git a/internal/test/issues/issue-2113/gen/api/api.gen.go b/internal/test/issues/issue-2113/gen/api/api.gen.go index 9aa3018f10..b8a5c4a533 100644 --- a/internal/test/issues/issue-2113/gen/api/api.gen.go +++ b/internal/test/issues/issue-2113/gen/api/api.gen.go @@ -194,7 +194,9 @@ func (response ListThings200JSONResponse) VisitListThingsResponse(w http.Respons return err } -type ListThings400JSONResponse struct{ externalRef0.StandardError } +type ListThings400JSONResponse struct { + externalRef0.StandardErrorJSONResponse +} func (response ListThings400JSONResponse) VisitListThingsResponse(w http.ResponseWriter) error { diff --git a/internal/test/issues/issue-2113/gen/common/common.gen.go b/internal/test/issues/issue-2113/gen/common/common.gen.go index 8d16de5f8f..6a6bc94a1c 100644 --- a/internal/test/issues/issue-2113/gen/common/common.gen.go +++ b/internal/test/issues/issue-2113/gen/common/common.gen.go @@ -11,3 +11,5 @@ type ProblemDetails struct { // StandardError defines model for StandardError. type StandardError = ProblemDetails + +type StandardErrorJSONResponse ProblemDetails diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go index 57ad01efb4..5a8e36dde0 100644 --- a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go @@ -215,7 +215,9 @@ type PostInvalidExtRefTroubleResponseObject interface { VisitPostInvalidExtRefTroubleResponse(w http.ResponseWriter) error } -type PostInvalidExtRefTrouble300JSONResponse struct{ externalRef0.Pascal } +type PostInvalidExtRefTrouble300JSONResponse struct { + externalRef0.PascalJSONResponse +} func (response PostInvalidExtRefTrouble300JSONResponse) VisitPostInvalidExtRefTroubleResponse(w http.ResponseWriter) error { diff --git a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl index baad4ab4e5..2a1905066e 100644 --- a/pkg/codegen/templates/strict/strict-fiber-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-interface.tmpl @@ -42,8 +42,6 @@ {{if and $fixedStatusCode $isRef -}} {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}} type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response - {{else if $isExternalRef -}} - type {{$receiverTypeName}} struct { {{$ref}} } {{else -}} type {{$receiverTypeName}} struct{ {{$ref}}{{.NameTagOrContentType}}Response } {{end}} diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 39fbc98855..237f668b1e 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -42,8 +42,6 @@ {{if and $fixedStatusCode $isRef -}} {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}} type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response - {{else if $isExternalRef -}} - type {{$receiverTypeName}} struct { {{$ref}} } {{else -}} type {{$receiverTypeName}} struct{ {{$ref}}{{.NameTagOrContentType}}Response } {{end}} diff --git a/pkg/codegen/templates/strict/strict-iris-interface.tmpl b/pkg/codegen/templates/strict/strict-iris-interface.tmpl index 5d9b5965c0..dbef961d3e 100644 --- a/pkg/codegen/templates/strict/strict-iris-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-iris-interface.tmpl @@ -42,8 +42,6 @@ {{if and $fixedStatusCode $isRef -}} {{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}} type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response - {{else if $isExternalRef -}} - type {{$receiverTypeName}} struct { {{$ref}} } {{else -}} type {{$receiverTypeName}} struct{ {{$ref}}{{.NameTagOrContentType}}Response } {{end}} From 08b30183ea8ab37db88e457634f2338f47222428 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Thu, 30 Apr 2026 22:37:33 -0700 Subject: [PATCH 61/62] Route server enums through general enums codegen (#2358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Route server enums through general enums codegen The server-URL codegen feature (`generate.server-urls: true`) re-implemented its own enum emission inside server-urls.tmpl rather than going through the generic GenerateEnums / GenerateTypes pipeline used by every other enum-bearing schema in the codebase. That self-contained path quietly accumulated five distinct bugs: * Two `const ...VariableDefault` declarations whenever an enum value's `ucFirst` form was the literal string `Default` (e.g. `enum: [default]`), producing uncompilable Go (#2003). * No `Valid()` method on enum-typed variables, with a literal "TODO ... will validate that the value is part of the ... enum" comment emitted in the generated function body (#2006). * Variables declared in `variables:` but absent from the URL still produced a type, constant, function parameter, and a no-op `strings.ReplaceAll` call (#2004). * `{name}` placeholders in the URL with no entry in `variables:` were left in the URL after substitution and tripped the trailing `{`/`}` runtime check on every call, making the generated function permanently unusable (#2005). * When `default` was set to a value not in `enum` (which OpenAPI 3 declares invalid), the template emitted `const FooDefault Foo = FooDevelopment` where `FooDevelopment` was never declared, surfacing the spec error as a confusing Go compile failure (#2007). All five share one root cause: server-URL variables didn't reach the type and enum codegen passes that already exist for every other schema. Changes: - Add `ForceEnumPrefix` to TypeDefinition. GenerateEnums OR's it into PrefixTypeName so synthesized server-URL enum types keep the existing always-prefixed identifier shape (`` rather than the bare `` the generic path would otherwise emit when no conflict is detected). - Add BuildServerURLTypeDefinitions in pkg/codegen/server_urls.go. It extracts enum-typed used variables from spec.Servers, synthesizes a TypeDefinition per variable, and validates `default ∈ enum` at codegen time so #2007 spec violations are caught with a clear error rather than emitted as broken Go. - Wire BuildServerURLTypeDefinitions into the `generate.server-urls` gate so the synthesized types flow through GenerateTypes (typedef.tmpl) and GenerateEnums (constants.tmpl) regardless of `generate.models`. This gives server-URL enum variables the same `type X string`, `const ( ... )` block, and `Valid()` method as any other enum-bearing schema. - Drop type/const emission for enum-typed variables from server-urls.tmpl; it now emits only the per-server function (which calls `.Valid()` on each enum-typed parameter) and any non-enum variable scaffolding. - Add ServerObjectDefinition.UsedVariables and UndeclaredPlaceholders helpers + extract serverObjectDefinitions, the name-deconfliction pass shared by both GenerateServerURLs and BuildServerURLTypeDefinitions, so the type pipeline and the function-body pipeline see the same identifiers. - Extend genServerURLWithVariablesFunctionParams to take undeclared placeholders, emitting them as plain `string` parameters alongside the declared variables (sorted together for stable output). User-visible naming change: for enum-typed server-URL variables only, the default-pointer constant is renamed from `Default` to `DefaultValue`. This is what makes the #2003 collision impossible permanently — the enum-value namespace and the default-pointer namespace are distinct regardless of what string values appear in the spec. Non-enum variables keep their existing `Default` naming. Enum-value identifiers also pick up an `N` prefix for digit-leading values (e.g. an enum value `8443` becomes `N8443`) since they now flow through SchemaNameToTypeName, matching how every other enum in the codegen names digit-leading values. The example fixture at examples/generate/serverurls/api.yaml gains two new servers: one with `enum: [default, 443]` to lock in the #2003 fix end-to-end, and one with an undeclared `{tenant}` placeholder for #2005. The existing `noDefault: {}` declared-but-unused variable now demonstrates the #2004 filtering. Three previously-identical localhost URLs are given unique ports (80/81/82) to comply with OpenAPI's URL-uniqueness requirement. Closes #2003 Closes #2004 Closes #2005 Closes #2006 Closes #2007 Supersedes #2045 Co-Authored-By: Claude Opus 4.7 (1M context) * Address PR #2358 review: minimize identifier churn Greptile's review flagged that the original PR shipped several unconditional behaviour changes to the generated API surface, none of which were intrinsic to the bug fixes: * `genServerURLWithVariablesFunctionParams` gained a third argument, breaking any user-supplied custom `server-urls.tmpl` override that called it with the previous two-argument form. * Digit-leading enum values acquired an `N` prefix (e.g. `Variable8443` became `VariableN8443`), an incidental side-effect of routing through `SchemaNameToTypeName` even though the enclosing type prefix already provided a leading letter. * The default-pointer constant was unconditionally renamed from `Default` to `DefaultValue` for every enum-typed variable, breaking adopters whose specs had no collision and whose code compiled cleanly under the old codegen. Greptile also identified a latent bug: when two enum values fold to the same identifier suffix (e.g. `enum: ["foo", "Foo"]`, both `ucFirst` to `Foo`), `SanitizeEnumNames`' numeric-suffix dedup produced `Foo` and `Foo1`, but the template's default-pointer emitted `{{ $v.Default | schemaNameToTypeName | sanitizeGoIdentity }}` without the suffix, so the pointer referenced an undeclared identifier. Changes: - Revert `genServerURLWithVariablesFunctionParams` to its original two-argument signature. A new `ServerObjectDefinition.NewServerFunctionParams` method now returns the full parameter list (typed declared variables plus plain-`string` undeclared placeholders, sorted together alphabetically), and the template calls `{{ .NewServerFunctionParams }}` instead of the helper. Any user-supplied custom template that calls `genServerURLWithVariablesFunctionParams` directly keeps working. - Replace `SanitizeEnumNames` (which forces digit-leading values through `SchemaNameToTypeName` and adds the `N` prefix) with a small in-package helper `serverURLEnumKeys` that uses `UppercaseFirstCharacter` directly, plus the same ``/`1`/`2` numeric-suffix dedup. Digit-leading values stay digit-leading; identifiers for non-colliding specs are byte-for-byte identical to what the pre-PR template produced. - Make the `Default` to `DefaultValue` rename asymmetric. A new `ServerObjectDefinition.EnumDefaultPointers` method pre-computes each enum-typed variable's default-pointer info; it switches to `DefaultValue` only when an enum value's identifier suffix is the literal string "Default" (i.e. exactly the spec pattern that produced #2003's duplicate-const compile error before this fix). Adopters whose specs compiled cleanly under the old codegen keep their `Default` constant. - The same `EnumDefaultPointers` data carries the post-dedup target identifier, so the template emits `const Default = Foo1` rather than recomputing via `schemaNameToTypeName | sanitizeGoIdentity`. The pointer always agrees with whatever name the const-block actually produced. - Drop the `schemaNameToTypeName` and `sanitizeGoIdentity` calls from `server-urls.tmpl` accordingly. The template now iterates pre-computed `.EnumDefaultPointers` and `.NewServerFunctionParams` rather than reconstructing identifier names itself. Test coverage: - `pkg/codegen/server_urls_test.go` gains four `TestEnumDefaultPointers` subtests pinning the asymmetric-rename behaviour, the post-dedup reference, and the absence of the `N` prefix. - `examples/generate/serverurls/api.yaml` adds a server with `enum: ["foo", "Foo"]` exercising the dedup case end-to-end. - `examples/generate/serverurls/gen_test.go` gains `TestServerUrlCaseOnlyEnumCollision` confirming the generated code compiles, the post-dedup constants are distinct, and the default-pointer references the right one. Net effect for adopters of the original `fix/enums` PR vs. `main`: * Helper signature unchanged. * Enum value identifiers unchanged for non-colliding specs. * Default-pointer constant name unchanged for non-colliding specs. * `noDefault`-style declared-but-unused parameters are still dropped (the #2004 fix; the parameter was a no-op). * Function calls `.Valid()` on enum-typed parameters (the #2006 fix). * Specs that previously failed to compile (#2003 collision, case-only-different enum values) now compile. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- examples/generate/serverurls/api.yaml | 53 +++- examples/generate/serverurls/gen.go | 148 ++++++++-- examples/generate/serverurls/gen_test.go | 112 ++++++-- pkg/codegen/codegen.go | 25 +- pkg/codegen/schema.go | 8 + pkg/codegen/server_urls.go | 346 +++++++++++++++++++++-- pkg/codegen/server_urls_test.go | 234 +++++++++++++++ pkg/codegen/template_helpers.go | 7 + pkg/codegen/templates/server-urls.tmpl | 85 ++++-- 9 files changed, 921 insertions(+), 97 deletions(-) create mode 100644 pkg/codegen/server_urls_test.go diff --git a/examples/generate/serverurls/api.yaml b/examples/generate/serverurls/api.yaml index ec7c73a5e2..53a5d807f8 100644 --- a/examples/generate/serverurls/api.yaml +++ b/examples/generate/serverurls/api.yaml @@ -26,22 +26,57 @@ servers: basePath: # open meaning there is the opportunity to use special base paths as assigned by the provider, default is `v2` default: v2 - # an example of a type that's defined, but doesn't have a default + # an example of a variable declared but NOT referenced in the URL. + # `oapi-codegen` filters these out so they don't pollute the + # generated function signature with no-op parameters + # (https://github.com/oapi-codegen/oapi-codegen/issues/2004). noDefault: {} - # # TODO this conflict will cause broken generated code https://github.com/oapi-codegen/oapi-codegen/issues/2003 - # conflicting: - # enum: - # - 'default' - # - '443' - # default: 'default' +# A server whose `port` enum literally includes the string `default`. +# The previous codegen tripped over this because the enum constant for +# the value `default` collided with the named default-pointer constant +# (https://github.com/oapi-codegen/oapi-codegen/issues/2003); the fix +# routes server-URL enums through the generic enum path and renames +# the default-pointer constant to `…VariableDefaultValue`. +- url: https://api.example.com/{port} + description: Conflicting default enum + variables: + port: + enum: + - 'default' + - '443' + default: 'default' +# A server whose URL contains a `{token}` placeholder for which there +# is no entry in `variables`. The previous codegen happily emitted a +# function that left `{token}` in the URL, which then tripped the +# trailing `{`/`}` runtime check on every call +# (https://github.com/oapi-codegen/oapi-codegen/issues/2005). The fix +# emits the undeclared placeholder as a plain `string` parameter so +# callers can fill it in. +- url: https://{tenant}.api.example.com + description: Undeclared placeholder server +# A server whose enum has two values that fold to the same Go +# identifier suffix (`foo` and `Foo` both `ucFirst` to `Foo`). The +# previous codegen would have emitted two `const ...VariableFoo` +# declarations and failed to compile; the synthesizer now appends a +# numeric suffix to disambiguate, and the typed default-pointer +# references the correct (post-suffix) enum constant — addressing the +# concern raised in PR #2358 review. +- url: https://api.example.com/{mode} + description: Case-only enum collision + variables: + mode: + enum: + - 'foo' + - 'Foo' + default: 'Foo' # clash with the previous definition of `Development server` to trigger a new name - url: http://localhost:80 description: Development server # clash with the previous definition of `Development server` to trigger a new name (again) -- url: http://localhost:80 +- url: http://localhost:81 description: Development server # make sure that the lowercase `description` gets converted to an uppercase -- url: http://localhost:80 +- url: http://localhost:82 description: some lowercase name # there may be URLs on their own, without a `description` - url: http://localhost:443 diff --git a/examples/generate/serverurls/gen.go b/examples/generate/serverurls/gen.go index b7d3485430..5f0feea91b 100644 --- a/examples/generate/serverurls/gen.go +++ b/examples/generate/serverurls/gen.go @@ -8,9 +8,112 @@ import ( "strings" ) +// ServerUrlCaseOnlyEnumCollisionModeVariable defines model for mode. +type ServerUrlCaseOnlyEnumCollisionModeVariable string + +// ServerUrlConflictingDefaultEnumPortVariable defines model for port. +type ServerUrlConflictingDefaultEnumPortVariable string + +// ServerUrlTheProductionAPIServerPortVariable defines model for port. +type ServerUrlTheProductionAPIServerPortVariable string + +// Defines values for ServerUrlCaseOnlyEnumCollisionModeVariable. +const ( + ServerUrlCaseOnlyEnumCollisionModeVariableFoo ServerUrlCaseOnlyEnumCollisionModeVariable = "foo" + ServerUrlCaseOnlyEnumCollisionModeVariableFoo1 ServerUrlCaseOnlyEnumCollisionModeVariable = "Foo" +) + +// Valid indicates whether the value is a known member of the ServerUrlCaseOnlyEnumCollisionModeVariable enum. +func (e ServerUrlCaseOnlyEnumCollisionModeVariable) Valid() bool { + switch e { + case ServerUrlCaseOnlyEnumCollisionModeVariableFoo: + return true + case ServerUrlCaseOnlyEnumCollisionModeVariableFoo1: + return true + default: + return false + } +} + +// Defines values for ServerUrlConflictingDefaultEnumPortVariable. +const ( + ServerUrlConflictingDefaultEnumPortVariable443 ServerUrlConflictingDefaultEnumPortVariable = "443" + ServerUrlConflictingDefaultEnumPortVariableDefault ServerUrlConflictingDefaultEnumPortVariable = "default" +) + +// Valid indicates whether the value is a known member of the ServerUrlConflictingDefaultEnumPortVariable enum. +func (e ServerUrlConflictingDefaultEnumPortVariable) Valid() bool { + switch e { + case ServerUrlConflictingDefaultEnumPortVariable443: + return true + case ServerUrlConflictingDefaultEnumPortVariableDefault: + return true + default: + return false + } +} + +// Defines values for ServerUrlTheProductionAPIServerPortVariable. +const ( + ServerUrlTheProductionAPIServerPortVariable443 ServerUrlTheProductionAPIServerPortVariable = "443" + ServerUrlTheProductionAPIServerPortVariable8443 ServerUrlTheProductionAPIServerPortVariable = "8443" +) + +// Valid indicates whether the value is a known member of the ServerUrlTheProductionAPIServerPortVariable enum. +func (e ServerUrlTheProductionAPIServerPortVariable) Valid() bool { + switch e { + case ServerUrlTheProductionAPIServerPortVariable443: + return true + case ServerUrlTheProductionAPIServerPortVariable8443: + return true + default: + return false + } +} + // MyCustomAPIServer defines the Server URL for Custom named server const MyCustomAPIServer = "https://api.example.com/v2" +// ServerUrlCaseOnlyEnumCollisionModeVariableDefault is the default choice, for the accepted values for the `mode` variable +const ServerUrlCaseOnlyEnumCollisionModeVariableDefault ServerUrlCaseOnlyEnumCollisionModeVariable = ServerUrlCaseOnlyEnumCollisionModeVariableFoo1 + +// NewServerUrlCaseOnlyEnumCollision constructs the Server URL for Case-only enum collision, with the provided variables. +func NewServerUrlCaseOnlyEnumCollision(mode ServerUrlCaseOnlyEnumCollisionModeVariable) (string, error) { + if !mode.Valid() { + return "", fmt.Errorf("`%v` is not one of the accepted values for the `mode` variable", mode) + } + + u := "https://api.example.com/{mode}" + + u = strings.ReplaceAll(u, "{mode}", string(mode)) + + if strings.Contains(u, "{") || strings.Contains(u, "}") { + return "", fmt.Errorf("after mapping variables, there were still `{` or `}` characters in the string: %#v", u) + } + + return u, nil +} + +// ServerUrlConflictingDefaultEnumPortVariableDefaultValue is the default choice, for the accepted values for the `port` variable +const ServerUrlConflictingDefaultEnumPortVariableDefaultValue ServerUrlConflictingDefaultEnumPortVariable = ServerUrlConflictingDefaultEnumPortVariableDefault + +// NewServerUrlConflictingDefaultEnum constructs the Server URL for Conflicting default enum, with the provided variables. +func NewServerUrlConflictingDefaultEnum(port ServerUrlConflictingDefaultEnumPortVariable) (string, error) { + if !port.Valid() { + return "", fmt.Errorf("`%v` is not one of the accepted values for the `port` variable", port) + } + + u := "https://api.example.com/{port}" + + u = strings.ReplaceAll(u, "{port}", string(port)) + + if strings.Contains(u, "{") || strings.Contains(u, "}") { + return "", fmt.Errorf("after mapping variables, there were still `{` or `}` characters in the string: %#v", u) + } + + return u, nil +} + // ServerUrlDevelopmentServer defines the Server URL for Development server const ServerUrlDevelopmentServer = "https://development.gigantic-server.com/v1" @@ -18,7 +121,7 @@ const ServerUrlDevelopmentServer = "https://development.gigantic-server.com/v1" const ServerUrlDevelopmentServer1 = "http://localhost:80" // ServerUrlDevelopmentServer2 defines the Server URL for Development server -const ServerUrlDevelopmentServer2 = "http://localhost:80" +const ServerUrlDevelopmentServer2 = "http://localhost:81" // ServerUrlHttplocalhost443 defines the Server URL for http://localhost:443 const ServerUrlHttplocalhost443 = "http://localhost:443" @@ -27,7 +130,7 @@ const ServerUrlHttplocalhost443 = "http://localhost:443" const ServerUrlProductionServer = "https://api.gigantic-server.com/v1" // ServerUrlSomeLowercaseName defines the Server URL for some lowercase name -const ServerUrlSomeLowercaseName = "http://localhost:80" +const ServerUrlSomeLowercaseName = "http://localhost:82" // ServerUrlStagingServer defines the Server URL for Staging server const ServerUrlStagingServer = "https://staging.gigantic-server.com/v1" @@ -38,35 +141,24 @@ type ServerUrlTheProductionAPIServerBasePathVariable string // ServerUrlTheProductionAPIServerBasePathVariableDefault is the default value for the `basePath` variable for ServerUrlTheProductionAPIServer const ServerUrlTheProductionAPIServerBasePathVariableDefault = "v2" -// ServerUrlTheProductionAPIServerNoDefaultVariable is the `noDefault` variable for ServerUrlTheProductionAPIServer -type ServerUrlTheProductionAPIServerNoDefaultVariable string - -// ServerUrlTheProductionAPIServerPortVariable is the `port` variable for ServerUrlTheProductionAPIServer -type ServerUrlTheProductionAPIServerPortVariable string - -// ServerUrlTheProductionAPIServerPortVariable8443 is one of the accepted values for the `port` variable for ServerUrlTheProductionAPIServer -const ServerUrlTheProductionAPIServerPortVariable8443 ServerUrlTheProductionAPIServerPortVariable = "8443" - -// ServerUrlTheProductionAPIServerPortVariable443 is one of the accepted values for the `port` variable for ServerUrlTheProductionAPIServer -const ServerUrlTheProductionAPIServerPortVariable443 ServerUrlTheProductionAPIServerPortVariable = "443" - -// ServerUrlTheProductionAPIServerPortVariableDefault is the default choice, for the accepted values for the `port` variable for ServerUrlTheProductionAPIServer -const ServerUrlTheProductionAPIServerPortVariableDefault ServerUrlTheProductionAPIServerPortVariable = ServerUrlTheProductionAPIServerPortVariable8443 - // ServerUrlTheProductionAPIServerUsernameVariable is the `username` variable for ServerUrlTheProductionAPIServer type ServerUrlTheProductionAPIServerUsernameVariable string // ServerUrlTheProductionAPIServerUsernameVariableDefault is the default value for the `username` variable for ServerUrlTheProductionAPIServer const ServerUrlTheProductionAPIServerUsernameVariableDefault = "demo" +// ServerUrlTheProductionAPIServerPortVariableDefault is the default choice, for the accepted values for the `port` variable +const ServerUrlTheProductionAPIServerPortVariableDefault ServerUrlTheProductionAPIServerPortVariable = ServerUrlTheProductionAPIServerPortVariable8443 + // NewServerUrlTheProductionAPIServer constructs the Server URL for The production API server, with the provided variables. -func NewServerUrlTheProductionAPIServer(basePath ServerUrlTheProductionAPIServerBasePathVariable, noDefault ServerUrlTheProductionAPIServerNoDefaultVariable, port ServerUrlTheProductionAPIServerPortVariable, username ServerUrlTheProductionAPIServerUsernameVariable) (string, error) { +func NewServerUrlTheProductionAPIServer(basePath ServerUrlTheProductionAPIServerBasePathVariable, port ServerUrlTheProductionAPIServerPortVariable, username ServerUrlTheProductionAPIServerUsernameVariable) (string, error) { + if !port.Valid() { + return "", fmt.Errorf("`%v` is not one of the accepted values for the `port` variable", port) + } + u := "https://{username}.gigantic-server.com:{port}/{basePath}" u = strings.ReplaceAll(u, "{basePath}", string(basePath)) - u = strings.ReplaceAll(u, "{noDefault}", string(noDefault)) - - // TODO in the future, this will validate that the value is part of the ServerUrlTheProductionAPIServerPortVariable enum u = strings.ReplaceAll(u, "{port}", string(port)) u = strings.ReplaceAll(u, "{username}", string(username)) @@ -76,3 +168,17 @@ func NewServerUrlTheProductionAPIServer(basePath ServerUrlTheProductionAPIServer return u, nil } + +// NewServerUrlUndeclaredPlaceholderServer constructs the Server URL for Undeclared placeholder server, with the provided variables. +func NewServerUrlUndeclaredPlaceholderServer(tenant string) (string, error) { + + u := "https://{tenant}.api.example.com" + + u = strings.ReplaceAll(u, "{tenant}", tenant) + + if strings.Contains(u, "{") || strings.Contains(u, "}") { + return "", fmt.Errorf("after mapping variables, there were still `{` or `}` characters in the string: %#v", u) + } + + return u, nil +} diff --git a/examples/generate/serverurls/gen_test.go b/examples/generate/serverurls/gen_test.go index 573fb5f2e5..6968ed3fe2 100644 --- a/examples/generate/serverurls/gen_test.go +++ b/examples/generate/serverurls/gen_test.go @@ -9,41 +9,51 @@ import ( ) func TestServerUrlTheProductionAPIServer(t *testing.T) { - t.Run("when no values are provided, it does not error", func(t *testing.T) { - serverUrl, err := NewServerUrlTheProductionAPIServer("", "", "", "") - require.NoError(t, err) - - assert.Equal(t, "https://.gigantic-server.com:/", serverUrl) - - // NOTE that ideally this should fail as it doesn't /seem/ to provide a valid URL, but it does seem to be valid - _, err = url.Parse(serverUrl) - require.NoError(t, err) + t.Run("when an empty value is provided for an enum-typed variable, it errors", func(t *testing.T) { + // `port` is enum-typed; the empty string is not in {"443", "8443"}. + _, err := NewServerUrlTheProductionAPIServer("", "", "") + require.Error(t, err) + assert.Contains(t, err.Error(), "port") }) - // TODO:when we validate enums, this will need more testing https://github.com/oapi-codegen/oapi-codegen/issues/2006 - t.Run("when values that are not part of the enum are provided, it does not error", func(t *testing.T) { + t.Run("when a value not in the enum is provided, it errors", func(t *testing.T) { invalidPort := ServerUrlTheProductionAPIServerPortVariable("12345") - serverUrl, err := NewServerUrlTheProductionAPIServer( + _, err := NewServerUrlTheProductionAPIServer( ServerUrlTheProductionAPIServerBasePathVariableDefault, - ServerUrlTheProductionAPIServerNoDefaultVariable(""), invalidPort, ServerUrlTheProductionAPIServerUsernameVariableDefault, ) - require.NoError(t, err) - - assert.Equal(t, "https://demo.gigantic-server.com:12345/v2", serverUrl) + require.Error(t, err) + assert.Contains(t, err.Error(), "port") }) t.Run("when default values are provided, it does not error", func(t *testing.T) { + // The default-pointer keeps its historical name on this server + // because the enum doesn't collide (no enum value folds to + // "Default") — the asymmetric rename for #2003 only kicks in + // when collision is detected. serverUrl, err := NewServerUrlTheProductionAPIServer( ServerUrlTheProductionAPIServerBasePathVariableDefault, - ServerUrlTheProductionAPIServerNoDefaultVariable(""), ServerUrlTheProductionAPIServerPortVariableDefault, ServerUrlTheProductionAPIServerUsernameVariableDefault, ) require.NoError(t, err) assert.Equal(t, "https://demo.gigantic-server.com:8443/v2", serverUrl) + + _, err = url.Parse(serverUrl) + require.NoError(t, err) + }) + + t.Run("a valid non-default enum value is accepted", func(t *testing.T) { + serverUrl, err := NewServerUrlTheProductionAPIServer( + ServerUrlTheProductionAPIServerBasePathVariableDefault, + ServerUrlTheProductionAPIServerPortVariable443, + ServerUrlTheProductionAPIServerUsernameVariableDefault, + ) + require.NoError(t, err) + + assert.Equal(t, "https://demo.gigantic-server.com:443/v2", serverUrl) }) } @@ -52,3 +62,71 @@ func TestXGoName(t *testing.T) { assert.Equal(t, "https://api.example.com/v2", MyCustomAPIServer) }) } + +// Regression test for #2003: an `enum` value `default` no longer +// collides with the default-pointer constant — both are emitted and +// the typed default-pointer correctly references the enum constant. +func TestServerUrlConflictingDefaultEnum(t *testing.T) { + t.Run("the default-pointer references the enum constant for `default`", func(t *testing.T) { + assert.Equal(t, + ServerUrlConflictingDefaultEnumPortVariable("default"), + ServerUrlConflictingDefaultEnumPortVariableDefaultValue, + ) + }) + + t.Run("New… accepts the default and the other enum value, errors on others", func(t *testing.T) { + got, err := NewServerUrlConflictingDefaultEnum(ServerUrlConflictingDefaultEnumPortVariableDefaultValue) + require.NoError(t, err) + assert.Equal(t, "https://api.example.com/default", got) + + got, err = NewServerUrlConflictingDefaultEnum(ServerUrlConflictingDefaultEnumPortVariable443) + require.NoError(t, err) + assert.Equal(t, "https://api.example.com/443", got) + + _, err = NewServerUrlConflictingDefaultEnum("nope") + require.Error(t, err) + }) +} + +// Regression test for #2005: a `{placeholder}` in the URL with no +// matching entry in `variables` is generated as a plain `string` +// parameter so the function returns a usable URL instead of always +// erroring on the trailing `{` / `}` check. +func TestServerUrlUndeclaredPlaceholderServer(t *testing.T) { + got, err := NewServerUrlUndeclaredPlaceholderServer("acme") + require.NoError(t, err) + assert.Equal(t, "https://acme.api.example.com", got) +} + +// Regression test for the case-only-different-enum scenario raised in +// PR #2358 review: `enum: [foo, Foo]` produces two values that +// `ucFirst`-fold to the same identifier `Foo`. The synthesizer dedups +// with a numeric suffix (`Foo` and `Foo1`) and the typed default-pointer +// references the post-suffix const that actually exists. Under the old +// codegen this would have emitted two `const ...VariableFoo` +// declarations and failed to compile. +func TestServerUrlCaseOnlyEnumCollision(t *testing.T) { + t.Run("default-pointer references the post-dedup constant", func(t *testing.T) { + // The spec sets default: "Foo"; the post-dedup const is + // ...VariableFoo1, which is exactly what the pointer must + // resolve to. + assert.Equal(t, + ServerUrlCaseOnlyEnumCollisionModeVariable("Foo"), + ServerUrlCaseOnlyEnumCollisionModeVariableDefault, + ) + assert.Equal(t, + ServerUrlCaseOnlyEnumCollisionModeVariableDefault, + ServerUrlCaseOnlyEnumCollisionModeVariableFoo1, + ) + }) + + t.Run("both case-variant constants are distinct and accepted", func(t *testing.T) { + got, err := NewServerUrlCaseOnlyEnumCollision(ServerUrlCaseOnlyEnumCollisionModeVariableFoo) + require.NoError(t, err) + assert.Equal(t, "https://api.example.com/foo", got) + + got, err = NewServerUrlCaseOnlyEnumCollision(ServerUrlCaseOnlyEnumCollisionModeVariableFoo1) + require.NoError(t, err) + assert.Equal(t, "https://api.example.com/Foo", got) + }) +} diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index afb0f0e3db..22317bda16 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -271,10 +271,31 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { var serverURLsDefinitions string if opts.Generate.ServerURLs { - serverURLsDefinitions, err = GenerateServerURLs(t, spec) + // Server-URL enum-typed variables are routed through the same + // typedef.tmpl + constants.tmpl pipelines as any other + // enum-bearing schema, so they get matching `type X string`, + // `const ( … )` block, and `Valid()` method. We do this here + // (rather than in GenerateTypeDefinitions) so the types are + // emitted even when `generate.models` is disabled. + serverURLEnumTypes, err := BuildServerURLTypeDefinitions(spec) + if err != nil { + return "", fmt.Errorf("error generating Go types for server URL variables: %w", err) + } + serverURLEnumTypeDecls, err := GenerateTypes(t, serverURLEnumTypes) + if err != nil { + return "", fmt.Errorf("error generating type declarations for server URL variables: %w", err) + } + serverURLEnumConstants, err := GenerateEnums(t, serverURLEnumTypes) + if err != nil { + return "", fmt.Errorf("error generating enums for server URL variables: %w", err) + } + + serverURLsBody, err := GenerateServerURLs(t, spec) if err != nil { return "", fmt.Errorf("error generating Server URLs: %w", err) } + + serverURLsDefinitions = serverURLEnumTypeDecls + serverURLEnumConstants + serverURLsBody } var irisServerOut string @@ -993,7 +1014,7 @@ func GenerateEnums(t *template.Template, types []TypeDefinition) (string, error) Schema: tp.Schema, TypeName: tp.TypeName, ValueWrapper: wrapper, - PrefixTypeName: globalState.options.Compatibility.AlwaysPrefixEnumValues, + PrefixTypeName: globalState.options.Compatibility.AlwaysPrefixEnumValues || tp.ForceEnumPrefix, }) } } diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index bf46a67a63..d9941381a1 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -259,6 +259,14 @@ type TypeDefinition struct { // This is the Schema wrapper is used to populate the type description Schema Schema + + // ForceEnumPrefix, when true, forces the enum-value constants generated + // from this TypeDefinition to be prefixed with the type name, regardless + // of whether GenerateEnums detects a cross-enum conflict. Used for + // synthesised enum types (e.g. server-URL variable enums) whose + // generated identifiers must remain stable to avoid colliding with + // other constants emitted alongside them. + ForceEnumPrefix bool } // ResponseTypeDefinition is an extension of TypeDefinition, specifically for diff --git a/pkg/codegen/server_urls.go b/pkg/codegen/server_urls.go index 48ef564d26..b70a52fd54 100644 --- a/pkg/codegen/server_urls.go +++ b/pkg/codegen/server_urls.go @@ -2,7 +2,10 @@ package codegen import ( "fmt" + "regexp" + "sort" "strconv" + "strings" "text/template" "github.com/getkin/kin-openapi/openapi3" @@ -11,6 +14,28 @@ import ( const serverURLPrefix = "ServerUrl" const serverURLSuffixIterations = 10 +// serverURLPlaceholderRE captures `{name}` placeholders in a Server URL +// template. Per OpenAPI 3.0.3 §4.7.7, server-variable names are bound to +// the {name} tokens in `Server Object` URL templates; we treat anything +// matching `{[^/{}]+}` as a placeholder candidate. The character class +// excludes `/` so we don't accidentally span path segments, and `{`/`}` +// so nested braces (which the spec doesn't define anyway) don't merge. +var serverURLPlaceholderRE = regexp.MustCompile(`\{([^/{}]+)\}`) + +// urlPlaceholders returns the set of variable names referenced as +// `{name}` placeholders in a Server URL template, deduplicated. +func urlPlaceholders(url string) map[string]struct{} { + matches := serverURLPlaceholderRE.FindAllStringSubmatch(url, -1) + if len(matches) == 0 { + return nil + } + set := make(map[string]struct{}, len(matches)) + for _, m := range matches { + set[m[1]] = struct{}{} + } + return set +} + // ServerObjectDefinition defines the definition of an OpenAPI Server object (https://spec.openapis.org/oas/v3.0.3#server-object) as it is provided to code generation in `oapi-codegen` type ServerObjectDefinition struct { // GoName is the name of the variable for this Server URL @@ -20,7 +45,63 @@ type ServerObjectDefinition struct { OAPISchema *openapi3.Server } -func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) { +// UsedVariables returns the subset of OAPISchema.Variables whose +// `{name}` placeholder actually appears in OAPISchema.URL. Variables +// declared but unused are skipped — they would otherwise produce a +// type, constant, function parameter, and a no-op `strings.ReplaceAll` +// (https://github.com/oapi-codegen/oapi-codegen/issues/2004). Used by +// both server-urls.tmpl and BuildServerURLTypeDefinitions so that +// emitted types and the generated function signature stay in sync. +func (s ServerObjectDefinition) UsedVariables() map[string]*openapi3.ServerVariable { + if s.OAPISchema == nil || len(s.OAPISchema.Variables) == 0 { + return nil + } + placeholders := urlPlaceholders(s.OAPISchema.URL) + used := make(map[string]*openapi3.ServerVariable, len(s.OAPISchema.Variables)) + for name, v := range s.OAPISchema.Variables { + if _, ok := placeholders[name]; ok { + used[name] = v + } + } + return used +} + +// UndeclaredPlaceholders returns the sorted list of `{name}` +// placeholder names that appear in OAPISchema.URL but have no +// corresponding entry in OAPISchema.Variables. The previous code +// generated a function that referenced only declared variables, so +// any undeclared placeholder remained in the URL after substitution +// and the trailing `{`/`}` runtime check tripped on every call — +// making the generated function permanently unusable +// (https://github.com/oapi-codegen/oapi-codegen/issues/2005). The +// template now adds these as plain `string` parameters so callers +// can fill them in directly. +func (s ServerObjectDefinition) UndeclaredPlaceholders() []string { + if s.OAPISchema == nil { + return nil + } + placeholders := urlPlaceholders(s.OAPISchema.URL) + if len(placeholders) == 0 { + return nil + } + var undeclared []string + for name := range placeholders { + if _, declared := s.OAPISchema.Variables[name]; !declared { + undeclared = append(undeclared, name) + } + } + if len(undeclared) == 0 { + return nil + } + sort.Strings(undeclared) + return undeclared +} + +// serverObjectDefinitions deconflicts server names and returns the +// stable, deterministically-named ServerObjectDefinitions for `spec`. +// Used by both BuildServerURLTypeDefinitions and GenerateServerURLs so +// they generate identifiers that match. +func serverObjectDefinitions(spec *openapi3.T) ([]ServerObjectDefinition, error) { names := make(map[string]*openapi3.Server) for _, server := range spec.Servers { @@ -28,7 +109,7 @@ func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) if goNameExt, ok := server.Extensions[extGoName]; ok { customName, err := extParseGoFieldName(goNameExt) if err != nil { - return "", fmt.Errorf("invalid value for %q: %w", extGoName, err) + return nil, fmt.Errorf("invalid value for %q: %w", extGoName, err) } if customName != "" { name = customName @@ -49,20 +130,11 @@ func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) continue } - // otherwise, try appending a number to the name + // otherwise, try appending a number to the name. Start at 1 so + // `Foo` / `Foo1` reads better than `Foo` / `Foo0`. saved := false - // NOTE that we start at 1 on purpose, as - // - // ... ServerURLDevelopmentServer - // ... ServerURLDevelopmentServer1` - // - // reads better than: - // - // ... ServerURLDevelopmentServer - // ... ServerURLDevelopmentServer0 for i := 1; i < 1+serverURLSuffixIterations; i++ { suffixed := name + strconv.Itoa(i) - // and then store it if there's no conflict if _, suffixConflict := names[suffixed]; !suffixConflict { names[suffixed] = server saved = true @@ -74,20 +146,258 @@ func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) continue } - // otherwise, error - return "", fmt.Errorf("failed to create a unique name for the Server URL (%#v) with description (%#v) after %d iterations", server.URL, server.Description, serverURLSuffixIterations) + return nil, fmt.Errorf("failed to create a unique name for the Server URL (%#v) with description (%#v) after %d iterations", server.URL, server.Description, serverURLSuffixIterations) } keys := SortedMapKeys(names) servers := make([]ServerObjectDefinition, len(keys)) - i := 0 - for _, k := range keys { + for i, k := range keys { servers[i] = ServerObjectDefinition{ GoName: k, OAPISchema: names[k], } - i++ + } + return servers, nil +} + +// serverURLVariableTypeName returns the Go type identifier for the +// `enum`-typed variable `varName` on the server with deconflicted Go +// name `serverGoName`. Mirrors the naming scheme used by +// server-urls.tmpl (`%sVariable`) so that synthesized +// TypeDefinitions, the function signature emitted by the template, +// and any user references all resolve to the same identifier. +func serverURLVariableTypeName(serverGoName, varName string) string { + return serverGoName + UppercaseFirstCharacter(varName) + "Variable" +} + +// serverURLEnumKeys returns deterministic identifier suffixes for each +// enum value of `v`, in `v.Enum` order. Each suffix is just the value +// with its first character upper-cased — matching what the previous +// template-only path produced for happy-path specs (``), +// so adopters with non-colliding enums keep their existing identifiers. +// +// When two values fold to the same suffix (e.g. `enum: ["foo", "FOO"]`, +// both → `Foo`), later occurrences get a numeric suffix (`Foo`, `Foo1`, +// `Foo2`, …) — same scheme as `SanitizeEnumNames`. The previous +// template path didn't dedup at all and would have produced a +// duplicate-const compile error for these specs; this is purely a +// correctness improvement, not a naming change for any spec that +// actually compiled before. +func serverURLEnumKeys(v *openapi3.ServerVariable) []string { + keys := make([]string, len(v.Enum)) + seen := make(map[string]int, len(v.Enum)) + for i, val := range v.Enum { + base := UppercaseFirstCharacter(val) + if n, dup := seen[base]; dup { + keys[i] = base + strconv.Itoa(n) + seen[base] = n + 1 + } else { + keys[i] = base + seen[base] = 1 + } + } + return keys +} + +// serverURLEnumValues returns the EnumValues map handed to GenerateEnums +// for variable `v`: key is the deduplicated identifier suffix from +// serverURLEnumKeys, value is the original enum string. +func serverURLEnumValues(v *openapi3.ServerVariable) map[string]string { + keys := serverURLEnumKeys(v) + out := make(map[string]string, len(keys)) + for i, k := range keys { + out[k] = v.Enum[i] + } + return out +} + +// ServerURLDefaultPointer carries the pre-computed identifier names +// needed to emit a typed default-pointer constant for an enum-typed +// server-URL variable. Computed in Go (not the template) so that the +// pointer's reference to the enum-value constant always agrees with +// the identifier the const-block actually emitted, including in +// dedup-suffix cases (e.g. `enum: ["foo", "FOO"]` with `default: "FOO"` +// → enum const is `Foo1`, pointer must reference exactly that). +type ServerURLDefaultPointer struct { + // VariableName is the OpenAPI variable name (for doc comments). + VariableName string + // TypeName is the enum's Go type, e.g. `ServerUrlFooBarVariable`. + TypeName string + // PointerName is the constant being declared. Normally it is + // `Default` (matching the historical naming). Switches + // to `DefaultValue` only when the variable's enum + // contains a value whose identifier suffix is the literal string + // "Default" — i.e. exactly the case that produced #2003's + // duplicate-const compile error under the old codegen. Specs that + // compiled cleanly before keep their `Default` name. + PointerName string + // TargetName is the fully-qualified enum-value constant that the + // pointer references, e.g. `N443` or `Foo1`. + TargetName string + // Description is the variable's OpenAPI description (doc comment). + Description string +} + +// NewServerFunctionParams returns the formatted parameter list for +// the generated `New(...)` function — one typed parameter +// per declared-and-used variable, plus one `string` parameter per +// `{name}` placeholder that appears in the URL but isn't in +// `variables` (#2005). The two groups are sorted together +// alphabetically so the generated signature is deterministic. +// +// Equivalent to calling `genServerURLWithVariablesFunctionParams` for +// the typed half and concatenating the undeclared half — but exposing +// it as a method keeps server-urls.tmpl free of that combination +// logic and means the template helper itself stayed at its +// pre-existing two-argument shape (so any user-supplied custom +// `server-urls.tmpl` override that calls the helper directly is +// unaffected). +func (s ServerObjectDefinition) NewServerFunctionParams() string { + used := s.UsedVariables() + undeclared := s.UndeclaredPlaceholders() + if len(used) == 0 && len(undeclared) == 0 { + return "" + } + + type param struct { + name string + typ string + } + parts := make([]param, 0, len(used)+len(undeclared)) + for _, k := range SortedMapKeys(used) { + parts = append(parts, param{ + name: k, + typ: serverURLVariableTypeName(s.GoName, k), + }) + } + for _, k := range undeclared { + parts = append(parts, param{name: k, typ: "string"}) + } + sort.Slice(parts, func(i, j int) bool { return parts[i].name < parts[j].name }) + + out := make([]string, len(parts)) + for i, p := range parts { + out[i] = p.name + " " + p.typ + } + return strings.Join(out, ", ") +} + +// EnumDefaultPointers returns one entry per enum-typed used variable +// with a `default` set. The template iterates this directly rather +// than recomputing identifier names from `$v.Default`. +func (s ServerObjectDefinition) EnumDefaultPointers() []ServerURLDefaultPointer { + used := s.UsedVariables() + var out []ServerURLDefaultPointer + for _, varName := range SortedMapKeys(used) { + v := used[varName] + if v == nil || len(v.Enum) == 0 || v.Default == "" { + continue + } + keys := serverURLEnumKeys(v) + var targetKey string + for i, val := range v.Enum { + if val == v.Default { + targetKey = keys[i] + break + } + } + if targetKey == "" { + // `default` not in `enum`; BuildServerURLTypeDefinitions + // already errors on this at codegen time, so we'd never + // actually reach the template emission. Skip defensively. + continue + } + prefix := serverURLVariableTypeName(s.GoName, varName) + pointerName := prefix + "Default" + for _, k := range keys { + if k == "Default" { + pointerName = prefix + "DefaultValue" + break + } + } + out = append(out, ServerURLDefaultPointer{ + VariableName: varName, + TypeName: prefix, + PointerName: pointerName, + TargetName: prefix + targetKey, + Description: v.Description, + }) + } + return out +} + +// BuildServerURLTypeDefinitions synthesizes a TypeDefinition for every +// server-URL variable that defines an `enum`. These are appended into +// the same TypeDefinition slices used by GenerateTypes (typedef.tmpl) +// and GenerateEnums (constants.tmpl), so that server-URL enum +// variables get the same `type X string`, `const ( … )` block, and +// `Valid()` method as any other enum-bearing schema. The +// server-urls.tmpl template no longer emits these declarations +// directly. +// +// Variables without an `enum` are not handled here: server-urls.tmpl +// continues to emit their `type` and (optional) default constant +// inline, since the generic enum path has nothing to contribute for a +// non-enum string. +func BuildServerURLTypeDefinitions(spec *openapi3.T) ([]TypeDefinition, error) { + servers, err := serverObjectDefinitions(spec) + if err != nil { + return nil, err } + var defs []TypeDefinition + for _, srv := range servers { + used := srv.UsedVariables() + // Iterate variables in deterministic order. + for _, varName := range SortedMapKeys(used) { + v := used[varName] + if v == nil || len(v.Enum) == 0 { + continue + } + // Validate that `default`, if set, is one of the + // declared `enum` values. Per OpenAPI 3.0.3 §4.7.10, + // the default MUST be in the enum list when both are + // present; the previous template trusted the spec + // blindly and emitted a const referencing an + // undeclared identifier when the spec violated the + // rule, producing a confusing user-side compile error + // (https://github.com/oapi-codegen/oapi-codegen/issues/2007). + // Catch the violation at codegen time so the user sees + // a clear message pointing at their spec. + if v.Default != "" { + inEnum := false + for _, ev := range v.Enum { + if ev == v.Default { + inEnum = true + break + } + } + if !inEnum { + return nil, fmt.Errorf("server URL %q: variable %q has default value %q which is not one of the declared enum values %v", + srv.OAPISchema.URL, varName, v.Default, v.Enum) + } + } + typeName := serverURLVariableTypeName(srv.GoName, varName) + enumValues := serverURLEnumValues(v) + defs = append(defs, TypeDefinition{ + TypeName: typeName, + JsonName: varName, + Schema: Schema{ + GoType: "string", + EnumValues: enumValues, + Description: v.Description, + }, + ForceEnumPrefix: true, + }) + } + } + return defs, nil +} + +func GenerateServerURLs(t *template.Template, spec *openapi3.T) (string, error) { + servers, err := serverObjectDefinitions(spec) + if err != nil { + return "", err + } return GenerateTemplates([]string{"server-urls.tmpl"}, t, servers) } diff --git a/pkg/codegen/server_urls_test.go b/pkg/codegen/server_urls_test.go new file mode 100644 index 0000000000..2105649bfb --- /dev/null +++ b/pkg/codegen/server_urls_test.go @@ -0,0 +1,234 @@ +package codegen + +import ( + "testing" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestURLPlaceholders(t *testing.T) { + t.Run("returns nil for a URL with no placeholders", func(t *testing.T) { + assert.Nil(t, urlPlaceholders("https://api.example.com/v1")) + }) + + t.Run("extracts a single placeholder", func(t *testing.T) { + got := urlPlaceholders("https://{host}.example.com/v1") + assert.Len(t, got, 1) + assert.Contains(t, got, "host") + }) + + t.Run("extracts multiple placeholders and dedupes repeats", func(t *testing.T) { + got := urlPlaceholders("https://{host}.example.com:{port}/{base}/{host}") + assert.Len(t, got, 3) + assert.Contains(t, got, "host") + assert.Contains(t, got, "port") + assert.Contains(t, got, "base") + }) + + t.Run("does not span across `/`", func(t *testing.T) { + // "{a/b}" must not be treated as a single placeholder named "a/b". + assert.Nil(t, urlPlaceholders("https://{a/b}.example.com")) + }) +} + +func TestUsedAndUndeclaredVariables(t *testing.T) { + srv := ServerObjectDefinition{ + GoName: "ServerUrlExample", + OAPISchema: &openapi3.Server{ + URL: "https://{host}.example.com:{port}/{path}", + Variables: map[string]*openapi3.ServerVariable{ + "host": {Default: "demo"}, + "port": {Default: "443", Enum: []string{"443", "8443"}}, + "unused": {Default: "x"}, // declared, but not referenced in URL + // "path" is referenced in URL but not declared + }, + }, + } + + used := srv.UsedVariables() + assert.Len(t, used, 2) + assert.Contains(t, used, "host") + assert.Contains(t, used, "port") + assert.NotContains(t, used, "unused", "declared-but-unused must be filtered (#2004)") + + undeclared := srv.UndeclaredPlaceholders() + assert.Equal(t, []string{"path"}, undeclared, "URL placeholder not in variables must be reported (#2005)") +} + +func TestBuildServerURLTypeDefinitions(t *testing.T) { + t.Run("synthesises one TypeDefinition per enum-typed used variable", func(t *testing.T) { + spec := &openapi3.T{ + Servers: openapi3.Servers{ + { + URL: "https://api.example.com:{port}", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "443", Enum: []string{"443", "8443"}}, + }, + }, + }, + } + defs, err := BuildServerURLTypeDefinitions(spec) + require.NoError(t, err) + require.Len(t, defs, 1) + assert.True(t, defs[0].ForceEnumPrefix, "server-URL enum types must keep prefixed identifiers") + assert.Equal(t, "string", defs[0].Schema.GoType) + assert.Len(t, defs[0].Schema.EnumValues, 2) + }) + + t.Run("skips non-enum variables", func(t *testing.T) { + spec := &openapi3.T{ + Servers: openapi3.Servers{ + { + URL: "https://{host}.example.com", + Variables: map[string]*openapi3.ServerVariable{ + "host": {Default: "demo"}, // no enum + }, + }, + }, + } + defs, err := BuildServerURLTypeDefinitions(spec) + require.NoError(t, err) + assert.Empty(t, defs) + }) + + t.Run("skips declared-but-unused variables (#2004)", func(t *testing.T) { + spec := &openapi3.T{ + Servers: openapi3.Servers{ + { + URL: "https://api.example.com", + Variables: map[string]*openapi3.ServerVariable{ + "unused": {Default: "443", Enum: []string{"443", "8443"}}, + }, + }, + }, + } + defs, err := BuildServerURLTypeDefinitions(spec) + require.NoError(t, err) + assert.Empty(t, defs) + }) + + t.Run("errors when default is not in enum (#2007)", func(t *testing.T) { + spec := &openapi3.T{ + Servers: openapi3.Servers{ + { + URL: "https://api.example.com:{port}", + Description: "Production API server", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "12345", Enum: []string{"443", "8443"}}, + }, + }, + }, + } + _, err := BuildServerURLTypeDefinitions(spec) + require.Error(t, err) + assert.Contains(t, err.Error(), "port") + assert.Contains(t, err.Error(), "12345") + }) + + t.Run("an enum value 'default' does not collide with the default-pointer (#2003)", func(t *testing.T) { + // Routing through GenerateEnums + emitting the default-pointer + // const with the asymmetric `…DefaultValue` rename means an + // enum literal "default" no longer produces a duplicate const + // declaration with the default pointer. + spec := &openapi3.T{ + Servers: openapi3.Servers{ + { + URL: "https://api.example.com:{port}", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "default", Enum: []string{"default", "443"}}, + }, + }, + }, + } + defs, err := BuildServerURLTypeDefinitions(spec) + require.NoError(t, err) + require.Len(t, defs, 1) + assert.Len(t, defs[0].Schema.EnumValues, 2) + }) +} + +// TestEnumDefaultPointers verifies the asymmetric default-pointer +// naming and the dedup-aware target reference — the two behaviours +// raised in the PR #2358 review. +func TestEnumDefaultPointers(t *testing.T) { + t.Run("happy-path enum keeps the historical `…Default` name", func(t *testing.T) { + // No enum value folds to the literal "Default", so there's no + // collision and the default-pointer keeps the pre-fix name. + // This is the asymmetric-rename criterion: only specs that + // would have collided under the old codegen see the rename. + srv := ServerObjectDefinition{ + GoName: "ServerUrlExample", + OAPISchema: &openapi3.Server{ + URL: "https://api.example.com:{port}", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "8443", Enum: []string{"443", "8443"}}, + }, + }, + } + ptrs := srv.EnumDefaultPointers() + require.Len(t, ptrs, 1) + assert.Equal(t, "ServerUrlExamplePortVariableDefault", ptrs[0].PointerName) + assert.Equal(t, "ServerUrlExamplePortVariable8443", ptrs[0].TargetName) + }) + + t.Run("colliding enum value triggers `…DefaultValue` rename (#2003)", func(t *testing.T) { + srv := ServerObjectDefinition{ + GoName: "ServerUrlExample", + OAPISchema: &openapi3.Server{ + URL: "https://api.example.com/{port}", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "default", Enum: []string{"default", "443"}}, + }, + }, + } + ptrs := srv.EnumDefaultPointers() + require.Len(t, ptrs, 1) + assert.Equal(t, "ServerUrlExamplePortVariableDefaultValue", ptrs[0].PointerName) + assert.Equal(t, "ServerUrlExamplePortVariableDefault", ptrs[0].TargetName, + "the target const for value \"default\" is …VariableDefault; the pointer is …VariableDefaultValue and references it") + }) + + t.Run("dedup-suffix value is referenced by the right name", func(t *testing.T) { + // `enum: [foo, Foo]` both `ucFirst`-fold to `Foo`; the second + // becomes `Foo1`. With `default: "Foo"` the pointer must + // reference …VariableFoo1, not …VariableFoo (which holds "foo"). + // Greptile flagged this in PR #2358 review. + srv := ServerObjectDefinition{ + GoName: "ServerUrlExample", + OAPISchema: &openapi3.Server{ + URL: "https://api.example.com/{mode}", + Variables: map[string]*openapi3.ServerVariable{ + "mode": {Default: "Foo", Enum: []string{"foo", "Foo"}}, + }, + }, + } + ptrs := srv.EnumDefaultPointers() + require.Len(t, ptrs, 1) + assert.Equal(t, "ServerUrlExampleModeVariableDefault", ptrs[0].PointerName, + "no enum value folds to `Default`, so no rename") + assert.Equal(t, "ServerUrlExampleModeVariableFoo1", ptrs[0].TargetName, + "target must be the post-suffix const for `Foo`, not the unsuffixed `Foo` which holds `foo`") + }) + + t.Run("digit-leading enum values do not pick up an `N` prefix", func(t *testing.T) { + // The previous PR-2358 implementation routed values through + // SchemaNameToTypeName, which prefixed digit-leading values + // with `N`. The current synthesis uses UppercaseFirstCharacter + // directly, so `8443` stays `8443` — preserving the + // pre-fix-PR identifier shape for happy-path adopters. + srv := ServerObjectDefinition{ + GoName: "ServerUrlExample", + OAPISchema: &openapi3.Server{ + URL: "https://api.example.com:{port}", + Variables: map[string]*openapi3.ServerVariable{ + "port": {Default: "443", Enum: []string{"443", "8443"}}, + }, + }, + } + ptrs := srv.EnumDefaultPointers() + require.Len(t, ptrs, 1) + assert.Equal(t, "ServerUrlExamplePortVariable443", ptrs[0].TargetName) + }) +} diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 1beaba0b3f..1b46105323 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -331,6 +331,13 @@ func stripNewLines(s string) string { // // goTypePrefix is the prefix being used to create underlying types in the template (likely the `ServerObjectDefinition.GoName`) // variables are this `ServerObjectDefinition`'s variables for the Server object (likely the `ServerObjectDefinition.OAPISchema`) +// +// Undeclared `{name}` placeholders that appear in the URL but have no +// entry in `variables` are NOT handled here; they're emitted as plain +// `string` parameters by `ServerObjectDefinition.NewFunctionParams`, +// which the template calls instead of this helper. Custom +// `server-urls.tmpl` overrides that still call this helper directly +// keep their pre-existing two-argument signature. func genServerURLWithVariablesFunctionParams(goTypePrefix string, variables map[string]*openapi3.ServerVariable) string { keys := SortedMapKeys(variables) diff --git a/pkg/codegen/templates/server-urls.tmpl b/pkg/codegen/templates/server-urls.tmpl index 3f1fdfe734..ccb1786e73 100644 --- a/pkg/codegen/templates/server-urls.tmpl +++ b/pkg/codegen/templates/server-urls.tmpl @@ -1,54 +1,79 @@ {{ range . }} -{{ if eq 0 (len .OAPISchema.Variables) }} -{{/* URLs without variables are straightforward, so we'll create them a constant */}} +{{ $usedVars := .UsedVariables }} +{{ $undeclared := .UndeclaredPlaceholders }} +{{ if and (eq 0 (len $usedVars)) (eq 0 (len $undeclared)) }} +{{/* URLs without variables (declared or used) are straightforward, so we'll create them a constant */}} // {{ .GoName }} defines the Server URL for {{ if len .OAPISchema.Description }}{{ .OAPISchema.Description }}{{ else }}{{ .OAPISchema.URL }}{{ end }} const {{ .GoName}} = "{{ .OAPISchema.URL }}" {{ else }} {{/* URLs with variables are not straightforward, as we may need multiple types, and so will model them as a function */}} -{{/* first, we'll start by generating requisite types */}} - {{ $goName := .GoName }} -{{ range $k, $v := .OAPISchema.Variables }} + +{{/* + For each USED variable, emit any inline declarations server-urls.tmpl + is still responsible for. Variables declared but not referenced by + a `{name}` placeholder in the URL are filtered out earlier + (https://github.com/oapi-codegen/oapi-codegen/issues/2004) so we + don't generate types/consts/params that the function would never + use. + + * Variables with `enum` get their `type` declaration and `const` + block (and a `Valid()` method) from typedef.tmpl + constants.tmpl + via GenerateEnums; here we only emit the optional default-pointer + constant — and we name it `…VariableDefaultValue` so it can never + collide with an enum value whose Go identifier is `Default` (e.g. + OpenAPI `enum: [default]`). + + * Variables without `enum` need their `type Foo string` and any + `const FooDefault = "…"` emitted here, since the generic enum + path has nothing to contribute for a non-enum string. +*/}} +{{ range $k, $v := $usedVars }} {{ $prefix := printf "%s%sVariable" $goName ($k | ucFirst) }} + {{ if eq (len $v.Enum) 0 }} // {{ $prefix }} is the `{{ $k }}` variable for {{ $goName }} type {{ $prefix }} string - {{ range $v.Enum }} - {{/* TODO this may result in broken generated code if any of the `enum` values are the literal value `default` https://github.com/oapi-codegen/oapi-codegen/issues/2003 */}} - // {{ $prefix }}{{ . | ucFirst }} is one of the accepted values for the `{{ $k }}` variable for {{ $goName }} - const {{ $prefix }}{{ . | ucFirst }} {{ $prefix }} = "{{ . }}" - {{ end }} - - {{/* TODO we should introduce a `Valid() error` method to enums https://github.com/oapi-codegen/oapi-codegen/issues/2006 */}} - {{ if $v.Default }} - {{ if gt (len $v.Enum) 0 }} - {{/* if we have an enum, we should use the type defined for it for its default value - and reference the constant we've already defined for the value */}} - {{/* TODO this may result in broken generated code if any of the `enum` values are the literal value `default` https://github.com/oapi-codegen/oapi-codegen/issues/2003 */}} - {{/* TODO this may result in broken generated code if the `default` isn't found in `enum` (which is an issue with the spec) https://github.com/oapi-codegen/oapi-codegen/issues/2007 */}} - // {{ $prefix }}Default is the default choice, for the accepted values for the `{{ $k }}` variable for {{ $goName }} - const {{ $prefix }}Default {{ $prefix }} = {{ $prefix }}{{ $v.Default | ucFirst }} - {{ else }} - // {{ $prefix }}Default is the default value for the `{{ $k }}` variable for {{ $goName }} - const {{ $prefix }}Default = "{{ $v.Default }}" - {{ end }} + // {{ $prefix }}Default is the default value for the `{{ $k }}` variable for {{ $goName }} + const {{ $prefix }}Default = "{{ $v.Default }}" {{ end }} + {{ end }} +{{ end }} + +{{/* + Enum-typed default-pointer constants. Their identifier names are + pre-computed in Go (ServerObjectDefinition.EnumDefaultPointers) so + that the pointer's reference to the enum-value constant always + matches the post-dedup name actually emitted by constants.tmpl, + and the pointer itself is renamed `…DefaultValue` only for specs + that would have collided under the old codegen anyway. +*/}} +{{ range .EnumDefaultPointers }} + // {{ .PointerName }} is the default choice, for the accepted values for the `{{ .VariableName }}` variable + const {{ .PointerName }} {{ .TypeName }} = {{ .TargetName }} {{ end }} // New{{ .GoName }} constructs the Server URL for {{ .OAPISchema.Description }}, with the provided variables. -func New{{ .GoName }}({{ genServerURLWithVariablesFunctionParams .GoName .OAPISchema.Variables }}) (string, error) { +func New{{ .GoName }}({{ .NewServerFunctionParams }}) (string, error) { + {{ range $k, $v := $usedVars }} + {{- if gt (len $v.Enum) 0 -}} + if !{{ $k }}.Valid() { + return "", fmt.Errorf("`%v` is not one of the accepted values for the `{{ $k }}` variable", {{ $k }}) + } + {{ end -}} + {{ end }} u := "{{ .OAPISchema.URL }}" - {{ range $k, $v := .OAPISchema.Variables }} + {{ range $k, $v := $usedVars }} {{- $placeholder := printf "{%s}" $k -}} - {{- if gt (len $v.Enum) 0 -}} - {{/* TODO https://github.com/oapi-codegen/oapi-codegen/issues/2006 */}} - // TODO in the future, this will validate that the value is part of the {{ printf "%s%sVariable" $goName ($k | ucFirst) }} enum - {{ end -}} u = strings.ReplaceAll(u, "{{ $placeholder }}", string({{ $k }})) {{ end }} + {{ range $k := $undeclared }} + {{- $placeholder := printf "{%s}" $k -}} + u = strings.ReplaceAll(u, "{{ $placeholder }}", {{ $k }}) + {{ end }} if strings.Contains(u, "{") || strings.Contains(u, "}") { return "", fmt.Errorf("after mapping variables, there were still `{` or `}` characters in the string: %#v", u) From b363ca5db8465d8772855797a8fb56918e8264b3 Mon Sep 17 00:00:00 2001 From: Gaiaz Iusipov Date: Fri, 1 May 2026 10:17:31 +0400 Subject: [PATCH 62/62] refactor(codegen): better Swagger compression, modern naming (#1909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(codegen): better Swagger compression * test(compatibility): Regenerate test spec * Add GetSpec/GetSpecJSON; revert const-concat embed format Three follow-ups to PR #1909, all in `pkg/codegen/templates/inline.tmpl` (plus the regenerated `*.gen.go` files and migrated callers): 1. Revert the embedded spec back to `var swaggerSpec = []string{...}`. PR #1909 replaced the historical slice-of-chunks form with a single `const swaggerSpec = "" + "chunk" + "chunk" + ...`. With thousands of 80-char chunks (large APIs produce them) the Go compiler folds the chained `+` at compile time, and that fold is materially slower than parsing a slice literal. `decodeSpec` now joins the slice via `strings.Join` before base64-decoding; flate compression, base64 encoding, the 80-char chunk size, the lazy `decodeSpecCached` / `rawSpec` pipeline, and `PathToRawSpec` all stay exactly as PR #1909 landed them. 2. Add `GetSpec() (*openapi3.T, error)` as the canonical accessor, and demote `GetSwagger()` to a `// Deprecated:` thin wrapper. The kin-openapi spec type was renamed from `openapi3.Swagger` to `openapi3.T` years ago; `GetSwagger`'s name is a stale relic. `GetSpec` carries the body that `GetSwagger` had, and `GetSwagger` becomes a one-line `return GetSpec()` retained for backwards compatibility. External callers still upgrading to a newer version of oapi-codegen will see the `// Deprecated:` hint surfaced by gopls/godoc; in-tree callers across `examples/` and `internal/test/` are migrated to `GetSpec()` because the repo's lint rule rejects calls into deprecated functions and would otherwise block CI. 3. Add `GetSpecJSON() ([]byte, error)` returning the embedded JSON. Decompressed, base64-decoded, but not unmarshaled into `*openapi3.T`. A one-line wrapper around the existing `rawSpec()` cache, so repeated calls don't re-decompress. This fills a long-standing gap: callers who want to operate on the raw OpenAPI document (re-marshal to YAML, hand to a different parser, run an overlay, dump to disk) previously had to either invoke `openapi3.T.MarshalJSON` after `GetSpec` or hand-roll base64+flate decode. Migrated callers (mechanical; no logic changes): - 7 user-side example files under `examples/` (petstore variants for each framework, authenticated-api echo + stdhttp). - 12 test files under `examples/petstore-expanded/*/petstore_test.go`, `internal/test/externalref/imports_test.go`, `internal/test/issues/issue1825/overlay_test.go`, `internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go`. New test: - `examples/petstore-expanded/chi/petstore_test.go::TestSpecAccess` covers `GetSpec` and `GetSpecJSON` end-to-end (asserts the bytes are valid JSON and the parsed spec has a non-empty `OpenAPI` version field). `GetSwagger` is intentionally not exercised — its body is `return GetSpec()` and the lint rule blocks an in-tree call. If we later want regression coverage for the wrapper specifically, one test annotated with `//nolint:staticcheck // SA1019` would do it. Verification: - `make generate` is idempotent; spot-checking `examples/petstore-expanded/chi/api/petstore.gen.go` confirms the slice form, the three new accessors, and the `// Deprecated:` marker on `GetSwagger`. - `make test` passes (exit 0) across the root module and all eight child modules. - `make lint` reports `0 issues.` across the same nine modules — no remaining in-tree calls into the deprecated wrapper. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Marcin Romaszewicz Co-authored-by: Claude Opus 4.7 (1M context) --- .../authenticated-api/echo/api/api.gen.go | 87 +++++---- .../authenticated-api/echo/server/server.go | 2 +- .../authenticated-api/stdhttp/api/api.gen.go | 87 +++++---- .../stdhttp/server/server.go | 2 +- examples/overlay/api/ping.gen.go | 76 +++++--- .../petstore-expanded/chi/api/petstore.gen.go | 120 +++++++------ examples/petstore-expanded/chi/petstore.go | 2 +- .../petstore-expanded/chi/petstore_test.go | 23 ++- .../echo-v5/api/petstore-server.gen.go | 116 +++++++----- .../petstore-expanded/echo-v5/petstore.go | 2 +- .../echo-v5/petstore_test.go | 2 +- .../echo/api/petstore-server.gen.go | 116 +++++++----- examples/petstore-expanded/echo/petstore.go | 2 +- .../petstore-expanded/echo/petstore_test.go | 2 +- .../echo/pkg_codegen_petstore_test.go | 8 +- .../fiber/api/petstore-server.gen.go | 116 +++++++----- examples/petstore-expanded/fiber/petstore.go | 2 +- .../gin/api/petstore-server.gen.go | 116 +++++++----- examples/petstore-expanded/gin/petstore.go | 2 +- .../gorilla/api/petstore.gen.go | 120 +++++++------ .../petstore-expanded/gorilla/petstore.go | 2 +- .../gorilla/petstore_test.go | 2 +- .../iris/api/petstore-server.gen.go | 118 +++++++------ examples/petstore-expanded/iris/petstore.go | 2 +- .../stdhttp/api/petstore.gen.go | 120 +++++++------ .../petstore-expanded/stdhttp/petstore.go | 2 +- .../stdhttp/petstore_test.go | 2 +- .../strict/api/petstore-server.gen.go | 120 +++++++------ examples/petstore-expanded/strict/petstore.go | 2 +- .../petstore-expanded/strict/petstore_test.go | 2 +- .../streaming/stdhttp/sse/streaming.gen.go | 74 +++++--- internal/test/all_of/v1/openapi.gen.go | 83 +++++---- internal/test/all_of/v2/openapi.gen.go | 83 +++++---- .../spec.gen.go | 69 +++++--- .../spec_test.go | 2 +- internal/test/externalref/externalref.gen.go | 77 +++++--- internal/test/externalref/imports_test.go | 8 +- .../externalref/packageA/externalref.gen.go | 73 +++++--- .../externalref/packageB/externalref.gen.go | 70 +++++--- .../externalref/petstore/externalref.gen.go | 165 ++++++++++-------- .../test/issues/issue-1087/deps/deps.gen.go | 90 ++++++---- .../issues/issue-1093/api/child/child.gen.go | 73 +++++--- .../issue-1093/api/parent/parent.gen.go | 73 +++++--- internal/test/issues/issue-1180/issue.gen.go | 73 +++++--- .../test/issues/issue-1182/pkg1/pkg1.gen.go | 71 +++++--- .../test/issues/issue-1182/pkg2/pkg2.gen.go | 69 +++++--- .../test/issues/issue-1189/issue1189.gen.go | 69 +++++--- .../issue-1208-1209/issue-multi-json.gen.go | 69 +++++--- .../test/issues/issue-1212/pkg1/pkg1.gen.go | 69 +++++--- .../test/issues/issue-1212/pkg2/pkg2.gen.go | 68 +++++--- .../issue-1378/bionicle/bionicle.gen.go | 73 +++++--- .../issues/issue-1378/common/common.gen.go | 68 +++++--- .../issue-1378/fooservice/fooservice.gen.go | 73 +++++--- .../test/issues/issue-1397/issue1397.gen.go | 74 +++++--- .../issue-1529/strict-echo/issue1529.gen.go | 69 +++++--- .../issue-1529/strict-fiber/issue1529.gen.go | 69 +++++--- .../issue-1529/strict-iris/issue1529.gen.go | 69 +++++--- internal/test/issues/issue-312/issue.gen.go | 83 +++++---- internal/test/issues/issue-52/issue.gen.go | 73 +++++--- internal/test/issues/issue-832/issue.gen.go | 73 +++++--- .../issue-grab_import_names/issue.gen.go | 72 +++++--- .../issue-illegal_enum_names/issue.gen.go | 70 +++++--- .../issue-illegal_enum_names/issue_test.go | 22 ++- .../test/issues/issue1825/issue1825.gen.go | 69 +++++--- .../test/issues/issue1825/overlay_test.go | 2 +- .../issue1825/packageA/externalref.gen.go | 65 ++++--- .../name_normalizer.gen.go | 82 +++++---- .../name_normalizer.gen.go | 82 +++++---- .../name_normalizer.gen.go | 82 +++++---- .../to-camel-case/name_normalizer.gen.go | 82 +++++---- .../unset/name_normalizer.gen.go | 82 +++++---- .../test/parameters/chi/gen/server.gen.go | 109 +++++++----- .../test/parameters/echo/gen/server.gen.go | 109 +++++++----- internal/test/parameters/echov5/server.gen.go | 109 +++++++----- .../test/parameters/fiber/gen/server.gen.go | 105 ++++++----- .../test/parameters/gin/gen/server.gen.go | 105 ++++++----- .../test/parameters/gorilla/gen/server.gen.go | 105 ++++++----- .../test/parameters/iris/gen/server.gen.go | 105 ++++++----- .../test/parameters/stdhttp/gen/server.gen.go | 105 ++++++----- internal/test/schemas/schemas.gen.go | 117 ++++++++----- internal/test/strict-server/chi/server.gen.go | 107 +++++++----- .../test/strict-server/echo/server.gen.go | 107 +++++++----- .../test/strict-server/fiber/server.gen.go | 107 +++++++----- internal/test/strict-server/gin/server.gen.go | 107 +++++++----- .../test/strict-server/gorilla/server.gen.go | 107 +++++++----- .../test/strict-server/iris/server.gen.go | 107 +++++++----- .../test/strict-server/stdhttp/server.gen.go | 107 +++++++----- pkg/codegen/inline.go | 21 +-- pkg/codegen/templates/imports.tmpl | 2 +- pkg/codegen/templates/inline.tmpl | 63 ++++--- 90 files changed, 3715 insertions(+), 2326 deletions(-) diff --git a/examples/authenticated-api/echo/api/api.gen.go b/examples/authenticated-api/echo/api/api.gen.go index 9cada0501d..d9b8dffea2 100644 --- a/examples/authenticated-api/echo/api/api.gen.go +++ b/examples/authenticated-api/echo/api/api.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -514,37 +514,39 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/8RUwW7bOBD9lcHsAnsRbCdZ7EE3B8kCDgq0aA3kEAcII44ttjLJDEdxjUD/XpCUHDVO", - "0/bUiy2Swzfz3rzhE1Zu650lKwHLJwxVTVuVPi+ZHccPz84Ti6G0XTlN8V9TqNh4Mc5imYMhnRW4drxV", - "giUaK2enWKDsPeUlbYixK3BLIajND4GG48PVIGzsBruuQKaH1jBpLG+wTziE33YFLusYeFS2VduU7W28", - "FHVAuTZSLy7iLdU079dY3jzh30xrLPGv6bNu0160aU7dFS9zGx1/x6r89+8rqryoxWi87W7jbqCqZSP7", - "TzFPhjwnxcTzVuq4uk+r/4cEV9dLLHIrY4J8+pywFvHYRWBj1+64BXML9FVtfUMw/7CAXW2qGtpAATIS", - "iPtCFkLlPAVQVsPV9RJUrKVAMdLEJLE0smIqJaQTzmXGxAIfiUNOdTKZTWbRD86TVd5giWdpq0CvpE5U", - "pxJlTZ8bkuNyP5K0bAMoaEwQcGvIFyZwTpVqA8V1ALLaO2MFtKNg/xFwj8RsdDymld007l41MEhdgBHo", - "uxGhI8O148Syp2Wcnawspto5LRcaS3xngixzxbGfwTsbcs9OZ7M8QFbIJiLK+6aHmn4Okc0wgck2Qtt0", - "8aee643aHVqsmNU+9/h7sV6KlGO8C68IO9c6Uk+BIC7qdCTxcixtOGgaUnDWdGUHUSFbMllmpO1dBit3", - "d9lTYCw41slo4Inj4IBa2R0bodckn2udRy8PEAU5d3r/W1r/wlgfizl/1sbYQCwTGMwY6ec90n3UzkgN", - "ysLiAseDLtxSd+SUkz/ulOWYwXLEAFprHlqKPMaPU3odx8/SDQ59ze/Ym7Ex4lsAAAD//9UBNUSMBgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "xFTBbts4EP2VwewCexFsJ1nsQTcHyQIOCrRoDeQQBwgjji22MskMR3GNQP9ekJQcNU7T9tSLLZLDN/Pe", + "vOETVm7rnSUrAcsnDFVNW5U+L5kdxw/PzhOLobRdOU3xX1Oo2HgxzmKZgyGdFbh2vFWCJRorZ6dYoOw9", + "5SVtiLErcEshqM0PgYbjw9UgbOwGu65ApofWMGksb7BPOITfdgUu6xh4VLZV25TtbbwUdUC5NlIvLuIt", + "1TTv11jePOHfTGss8a/ps27TXrRpTt0VL3MbHX/Hqvz37yuqvKjFaLztbuNuoKplI/tPMU+GPCfFxPNW", + "6ri6T6v/hwRX10sscitjgnz6nLAW8dhFYGPX7rgFcwv0VW19QzD/sIBdbaoa2kABMhKI+0IWQuU8BVBW", + "w9X1ElSspUAx0sQksTSyYiolpBPOZcbEAh+JQ051MplNZtEPzpNV3mCJZ2mrQK+kTlSnEmVNnxuS43I/", + "krRsAyhoTBBwa8gXJnBOlWoDxXUAsto7YwW0o2D/EXCPxGx0PKaV3TTuXjUwSF2AEei7EaEjw7XjxLKn", + "ZZydrCym2jktFxpLfGeCLHPFsZ/BOxtyz05nszxAVsgmIsr7poeafg6RzTCByTZC23Txp57rjdodWqyY", + "1T73+HuxXoqUY7wLrwg71zpST4EgLup0JPFyLG04aBpScNZ0ZQdRIVsyWWak7V0GK3d32VNgLDjWyWjg", + "iePggFrZHRuh1ySfa51HLw8QBTl3ev9bWv/CWB+LOX/WxthALBMYzBjp5z3SfdTOSA3KwuICx4Mu3FJ3", + "5JSTP+6U5ZjBcsQAWmseWoo8xo9Teh3Hz9INDn3N79ibsTHiWwAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -552,7 +554,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -570,12 +572,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -601,3 +603,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/authenticated-api/echo/server/server.go b/examples/authenticated-api/echo/server/server.go index 5346b77e28..fbd9bd1598 100644 --- a/examples/authenticated-api/echo/server/server.go +++ b/examples/authenticated-api/echo/server/server.go @@ -26,7 +26,7 @@ func NewServer() *server { } func CreateMiddleware(v JWSValidator) ([]echo.MiddlewareFunc, error) { - spec, err := api.GetSwagger() + spec, err := api.GetSpec() if err != nil { return nil, fmt.Errorf("loading spec: %w", err) } diff --git a/examples/authenticated-api/stdhttp/api/api.gen.go b/examples/authenticated-api/stdhttp/api/api.gen.go index 5a83732c25..97f16b2ff2 100644 --- a/examples/authenticated-api/stdhttp/api/api.gen.go +++ b/examples/authenticated-api/stdhttp/api/api.gen.go @@ -7,7 +7,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -611,37 +611,39 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H return m } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/8RUwW7bOBD9lcHsAnsRbCdZ7EE3B8kCDgq0aA3kEAcII44ttjLJDEdxjUD/XpCUHDVO", - "0/bUiy2Swzfz3rzhE1Zu650lKwHLJwxVTVuVPi+ZHccPz84Ti6G0XTlN8V9TqNh4Mc5imYMhnRW4drxV", - "giUaK2enWKDsPeUlbYixK3BLIajND4GG48PVIGzsBruuQKaH1jBpLG+wTziE33YFLusYeFS2VduU7W28", - "FHVAuTZSLy7iLdU079dY3jzh30xrLPGv6bNu0160aU7dFS9zGx1/x6r89+8rqryoxWi87W7jbqCqZSP7", - "TzFPhjwnxcTzVuq4uk+r/4cEV9dLLHIrY4J8+pywFvHYRWBj1+64BXML9FVtfUMw/7CAXW2qGtpAATIS", - "iPtCFkLlPAVQVsPV9RJUrKVAMdLEJLE0smIqJaQTzmXGxAIfiUNOdTKZTWbRD86TVd5giWdpq0CvpE5U", - "pxJlTZ8bkuNyP5K0bAMoaEwQcGvIFyZwTpVqA8V1ALLaO2MFtKNg/xFwj8RsdDymld007l41MEhdgBHo", - "uxGhI8O148Syp2Wcnawspto5LRcaS3xngixzxbGfwTsbcs9OZ7M8QFbIJiLK+6aHmn4Okc0wgck2Qtt0", - "8aee643aHVqsmNU+9/h7sV6KlGO8C68IO9c6Uk+BIC7qdCTxcixtOGgaUnDWdGUHUSFbMllmpO1dBit3", - "d9lTYCw41slo4Inj4IBa2R0bodckn2udRy8PEAU5d3r/W1r/wlgfizl/1sbYQCwTGMwY6ec90n3UzkgN", - "ysLiAseDLtxSd+SUkz/ulOWYwXLEAFprHlqKPMaPU3odx8/SDQ59ze/Ym7Ex4lsAAAD//9UBNUSMBgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "xFTBbts4EP2VwewCexFsJ1nsQTcHyQIOCrRoDeQQBwgjji22MskMR3GNQP9ekJQcNU7T9tSLLZLDN/Pe", + "vOETVm7rnSUrAcsnDFVNW5U+L5kdxw/PzhOLobRdOU3xX1Oo2HgxzmKZgyGdFbh2vFWCJRorZ6dYoOw9", + "5SVtiLErcEshqM0PgYbjw9UgbOwGu65ApofWMGksb7BPOITfdgUu6xh4VLZV25TtbbwUdUC5NlIvLuIt", + "1TTv11jePOHfTGss8a/ps27TXrRpTt0VL3MbHX/Hqvz37yuqvKjFaLztbuNuoKplI/tPMU+GPCfFxPNW", + "6ri6T6v/hwRX10sscitjgnz6nLAW8dhFYGPX7rgFcwv0VW19QzD/sIBdbaoa2kABMhKI+0IWQuU8BVBW", + "w9X1ElSspUAx0sQksTSyYiolpBPOZcbEAh+JQ051MplNZtEPzpNV3mCJZ2mrQK+kTlSnEmVNnxuS43I/", + "krRsAyhoTBBwa8gXJnBOlWoDxXUAsto7YwW0o2D/EXCPxGx0PKaV3TTuXjUwSF2AEei7EaEjw7XjxLKn", + "ZZydrCym2jktFxpLfGeCLHPFsZ/BOxtyz05nszxAVsgmIsr7poeafg6RzTCByTZC23Txp57rjdodWqyY", + "1T73+HuxXoqUY7wLrwg71zpST4EgLup0JPFyLG04aBpScNZ0ZQdRIVsyWWak7V0GK3d32VNgLDjWyWjg", + "iePggFrZHRuh1ySfa51HLw8QBTl3ev9bWv/CWB+LOX/WxthALBMYzBjp5z3SfdTOSA3KwuICx4Mu3FJ3", + "5JSTP+6U5ZjBcsQAWmseWoo8xo9Teh3Hz9INDn3N79ibsTHiWwAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -649,7 +651,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -667,12 +669,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -698,3 +700,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/authenticated-api/stdhttp/server/server.go b/examples/authenticated-api/stdhttp/server/server.go index ddcabaa737..6ed2da28e9 100644 --- a/examples/authenticated-api/stdhttp/server/server.go +++ b/examples/authenticated-api/stdhttp/server/server.go @@ -27,7 +27,7 @@ func NewServer() *server { } func CreateMiddleware(v JWSValidator) (func(next http.Handler) http.Handler, error) { - spec, err := api.GetSwagger() + spec, err := api.GetSpec() if err != nil { return nil, fmt.Errorf("loading spec: %w", err) } diff --git a/examples/overlay/api/ping.gen.go b/examples/overlay/api/ping.gen.go index 757cd1c6b4..0d6794fc38 100644 --- a/examples/overlay/api/ping.gen.go +++ b/examples/overlay/api/ping.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/http" @@ -170,34 +170,35 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/1xSwW7UMBD9FWvgAFJ2ve2Ki28VQmjFYVeCW9WD60xil8Rj7ElpVfnf0Ti7FHqaePLs", - "997MewFHc6KIkQuYFyjO42zb54niKDVlSpg5YOumsHbxyc5pQjCQBNcBPyc5Fc6CqLWDjL+WkLEHc7te", - "u/uLovsHdAwdPG1G2kQ7S/P4iDmHvsfYqKu8EeJAQseBG9mXlVYxqRD74Cyj8vRbzktBxR7VMWG8OR2U", - "PDfZZ1USujAINFBUHzxzKkbrMbBf7reOZn28OegzevP9X/RH6OARcwkUwcDVdrfdNc10BtuUpiAGxfbi", - "eMnYX35C7YASRpsCGNif7ybLvs1R234OUduFqTg7rVOtHejLgEdkKT0Wl0PiVcJnj+6nYm+5WRWboai8", - "xBjiqI7foHHmJv4gur4in0LbT8aSKJZ1i9e7nRRHkTE2nmZlda0fipBdwiBf7zMOYOCdfk2LPkdFvy7r", - "f60nzAPlWVkllpSkAQu3ZBTMMlYwt28N/vCoehzsMrFaUVvoYMkTGJDNGa0ncnbyVNjsP11d76He1Vrr", - "nwAAAP//QsRK0MkCAAA=", + "XFLBbtQwEP0Va+AAUna97YqLbxVCaMVhV4Jb1YPrTGKXxGPsSWlV+d/ROLsUepp48uz33sx7AUdzooiR", + "C5gXKM7jbNvnieIoNWVKmDlg66awdvHJzmlCMJAE1wE/JzkVzoKotYOMv5aQsQdzu167+4ui+wd0DB08", + "bUbaRDtL8/iIOYe+x9ioq7wR4kBCx4Eb2ZeVVjGpEPvgLKPy9FvOS0HFHtUxYbw5HZQ8N9lnVRK6MAg0", + "UFQfPHMqRusxsF/ut45mfbw56DN68/1f9Efo4BFzCRTBwNV2t901zXQG25SmIAbF9uJ4ydhffkLtgBJG", + "mwIY2J/vJsu+zVHbfg5R24WpODutU60d6MuAR2QpPRaXQ+JVwmeP7qdib7lZFZuhqLzEGOKojt+gceYm", + "/iC6viKfQttPxpIolnWL17udFEeRMTaeZmV1rR+KkF3CIF/vMw5g4J1+TYs+R0W/Lut/rSfMA+VZWSWW", + "lKQBC7dkFMwyVjC3bw3+8Kh6HOwysVpRW+hgyRMYkM0ZrSdydvJU2Ow/XV3vod7VWuufAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -205,7 +206,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -223,12 +224,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -254,3 +255,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/chi/api/petstore.gen.go b/examples/petstore-expanded/chi/api/petstore.gen.go index f599568124..338c39e73f 100644 --- a/examples/petstore-expanded/chi/api/petstore.gen.go +++ b/examples/petstore-expanded/chi/api/petstore.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "errors" "fmt" @@ -355,54 +355,55 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -410,7 +411,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -428,12 +429,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -459,3 +460,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/chi/petstore.go b/examples/petstore-expanded/chi/petstore.go index b525fa5763..644b4920ea 100644 --- a/examples/petstore-expanded/chi/petstore.go +++ b/examples/petstore-expanded/chi/petstore.go @@ -21,7 +21,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/chi/petstore_test.go b/examples/petstore-expanded/chi/petstore_test.go index e9d7662b45..86a9e2cd34 100644 --- a/examples/petstore-expanded/chi/petstore_test.go +++ b/examples/petstore-expanded/chi/petstore_test.go @@ -20,11 +20,32 @@ func doGet(t *testing.T, mux *chi.Mux, url string) *httptest.ResponseRecorder { return response.Recorder } +// TestSpecAccess covers the public spec accessors emitted by inline.tmpl: +// - GetSpec returns a parsed *openapi3.T +// - GetSpecJSON returns the raw JSON bytes (decompressed but unparsed), +// which must be valid JSON. +// +// GetSwagger is intentionally not exercised here: it's marked +// `// Deprecated:` and the repo's lint rule rejects in-tree calls to +// deprecated functions. Its body is `return GetSpec()`, so its behaviour +// is covered transitively. +func TestSpecAccess(t *testing.T) { + spec, err := api.GetSpec() + require.NoError(t, err) + require.NotNil(t, spec) + assert.NotEmpty(t, spec.OpenAPI, "OpenAPI version field must be populated") + + raw, err := api.GetSpecJSON() + require.NoError(t, err) + require.NotEmpty(t, raw, "raw spec bytes must be non-empty") + assert.True(t, json.Valid(raw), "GetSpecJSON must return valid JSON") +} + func TestPetStore(t *testing.T) { var err error // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // Clear out the servers array in the swagger spec, that skips validating diff --git a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go index 7dc2404777..557c96abf5 100644 --- a/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go +++ b/examples/petstore-expanded/echo-v5/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/http" @@ -160,54 +160,55 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -215,7 +216,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -233,12 +234,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -264,3 +265,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/echo-v5/petstore.go b/examples/petstore-expanded/echo-v5/petstore.go index 9742cc1939..7b15a9fdd5 100644 --- a/examples/petstore-expanded/echo-v5/petstore.go +++ b/examples/petstore-expanded/echo-v5/petstore.go @@ -21,7 +21,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/echo-v5/petstore_test.go b/examples/petstore-expanded/echo-v5/petstore_test.go index 61d0530a23..3809bb5544 100644 --- a/examples/petstore-expanded/echo-v5/petstore_test.go +++ b/examples/petstore-expanded/echo-v5/petstore_test.go @@ -37,7 +37,7 @@ func TestPetStore(t *testing.T) { store := api.NewPetStore() // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // This disables swagger server name validation. It seems to work poorly, diff --git a/examples/petstore-expanded/echo/api/petstore-server.gen.go b/examples/petstore-expanded/echo/api/petstore-server.gen.go index 8565fafd5e..8a65c64304 100644 --- a/examples/petstore-expanded/echo/api/petstore-server.gen.go +++ b/examples/petstore-expanded/echo/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/http" @@ -160,54 +160,55 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -215,7 +216,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -233,12 +234,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -264,3 +265,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/echo/petstore.go b/examples/petstore-expanded/echo/petstore.go index 7287d2b354..a764f00b04 100644 --- a/examples/petstore-expanded/echo/petstore.go +++ b/examples/petstore-expanded/echo/petstore.go @@ -20,7 +20,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/echo/petstore_test.go b/examples/petstore-expanded/echo/petstore_test.go index 092e6238e8..eb3b8c1652 100644 --- a/examples/petstore-expanded/echo/petstore_test.go +++ b/examples/petstore-expanded/echo/petstore_test.go @@ -37,7 +37,7 @@ func TestPetStore(t *testing.T) { store := api.NewPetStore() // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // This disables swagger server name validation. It seems to work poorly, diff --git a/examples/petstore-expanded/echo/pkg_codegen_petstore_test.go b/examples/petstore-expanded/echo/pkg_codegen_petstore_test.go index de651ec54f..1f13ce4784 100644 --- a/examples/petstore-expanded/echo/pkg_codegen_petstore_test.go +++ b/examples/petstore-expanded/echo/pkg_codegen_petstore_test.go @@ -38,7 +38,7 @@ func TestExamplePetStoreCodeGeneration(t *testing.T) { } // Get a spec from the example PetStore definition: - swagger, err := examplePetstore.GetSwagger() + swagger, err := examplePetstore.GetSpec() assert.NoError(t, err) // Run our code generation: @@ -85,7 +85,7 @@ func TestExamplePetStoreCodeGenerationWithUserTemplates(t *testing.T) { } // Get a spec from the example PetStore definition: - swagger, err := examplePetstore.GetSwagger() + swagger, err := examplePetstore.GetSpec() assert.NoError(t, err) // Run our code generation: @@ -121,7 +121,7 @@ func TestExamplePetStoreCodeGenerationWithFileUserTemplates(t *testing.T) { } // Get a spec from the example PetStore definition: - swagger, err := examplePetstore.GetSwagger() + swagger, err := examplePetstore.GetSpec() assert.NoError(t, err) // Run our code generation: @@ -162,7 +162,7 @@ func TestExamplePetStoreCodeGenerationWithHTTPUserTemplates(t *testing.T) { } // Get a spec from the example PetStore definition: - swagger, err := examplePetstore.GetSwagger() + swagger, err := examplePetstore.GetSpec() assert.NoError(t, err) // Run our code generation: diff --git a/examples/petstore-expanded/fiber/api/petstore-server.gen.go b/examples/petstore-expanded/fiber/api/petstore-server.gen.go index c8f2b20b48..fe76a2fba4 100644 --- a/examples/petstore-expanded/fiber/api/petstore-server.gen.go +++ b/examples/petstore-expanded/fiber/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -195,54 +195,55 @@ func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, option } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -250,7 +251,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -268,12 +269,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -299,3 +300,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/fiber/petstore.go b/examples/petstore-expanded/fiber/petstore.go index 6332ff8866..eb6ddac31c 100644 --- a/examples/petstore-expanded/fiber/petstore.go +++ b/examples/petstore-expanded/fiber/petstore.go @@ -32,7 +32,7 @@ func main() { func NewFiberPetServer(petStore *api.PetStore) *fiber.App { - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/gin/api/petstore-server.gen.go b/examples/petstore-expanded/gin/api/petstore-server.gen.go index 52ce7a8087..4a2d6f9e5c 100644 --- a/examples/petstore-expanded/gin/api/petstore-server.gen.go +++ b/examples/petstore-expanded/gin/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/http" @@ -174,54 +174,55 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.GET(options.BaseURL+"/pets/:id", wrapper.FindPetByID) } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -229,7 +230,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -247,12 +248,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -278,3 +279,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/gin/petstore.go b/examples/petstore-expanded/gin/petstore.go index 8b0717a4c8..0c0a7e1589 100644 --- a/examples/petstore-expanded/gin/petstore.go +++ b/examples/petstore-expanded/gin/petstore.go @@ -19,7 +19,7 @@ import ( ) func NewGinPetServer(petStore *api.PetStore, port string) *http.Server { - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/gorilla/api/petstore.gen.go b/examples/petstore-expanded/gorilla/api/petstore.gen.go index dea4e55e54..3ed8b4c27e 100644 --- a/examples/petstore-expanded/gorilla/api/petstore.gen.go +++ b/examples/petstore-expanded/gorilla/api/petstore.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "errors" "fmt" @@ -322,54 +322,55 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -377,7 +378,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -395,12 +396,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -426,3 +427,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/gorilla/petstore.go b/examples/petstore-expanded/gorilla/petstore.go index d1675f1ae3..8a6eac558c 100644 --- a/examples/petstore-expanded/gorilla/petstore.go +++ b/examples/petstore-expanded/gorilla/petstore.go @@ -21,7 +21,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/gorilla/petstore_test.go b/examples/petstore-expanded/gorilla/petstore_test.go index a6cfedecd8..c3dc320f0b 100644 --- a/examples/petstore-expanded/gorilla/petstore_test.go +++ b/examples/petstore-expanded/gorilla/petstore_test.go @@ -24,7 +24,7 @@ func TestPetStore(t *testing.T) { var err error // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // Clear out the servers array in the swagger spec, that skips validating diff --git a/examples/petstore-expanded/iris/api/petstore-server.gen.go b/examples/petstore-expanded/iris/api/petstore-server.gen.go index 9f52757c5c..f5bcd2cb29 100644 --- a/examples/petstore-expanded/iris/api/petstore-server.gen.go +++ b/examples/petstore-expanded/iris/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/http" @@ -144,54 +144,55 @@ func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, o router.Build() } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", +} - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -199,7 +200,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -217,12 +218,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -248,3 +249,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/iris/petstore.go b/examples/petstore-expanded/iris/petstore.go index 2b2dea37f7..b97b95c5c6 100644 --- a/examples/petstore-expanded/iris/petstore.go +++ b/examples/petstore-expanded/iris/petstore.go @@ -17,7 +17,7 @@ import ( ) func NewIrisPetServer(petStore *api.PetStore, port int) *iris.Application { - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/stdhttp/api/petstore.gen.go b/examples/petstore-expanded/stdhttp/api/petstore.gen.go index aa60a0891e..9ae158e3fd 100644 --- a/examples/petstore-expanded/stdhttp/api/petstore.gen.go +++ b/examples/petstore-expanded/stdhttp/api/petstore.gen.go @@ -7,7 +7,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "errors" "fmt" @@ -327,54 +327,55 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H return m } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -382,7 +383,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -400,12 +401,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -431,3 +432,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/stdhttp/petstore.go b/examples/petstore-expanded/stdhttp/petstore.go index 68e45cc1d7..043e60b841 100644 --- a/examples/petstore-expanded/stdhttp/petstore.go +++ b/examples/petstore-expanded/stdhttp/petstore.go @@ -22,7 +22,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/stdhttp/petstore_test.go b/examples/petstore-expanded/stdhttp/petstore_test.go index bf3df022d2..ce6322c946 100644 --- a/examples/petstore-expanded/stdhttp/petstore_test.go +++ b/examples/petstore-expanded/stdhttp/petstore_test.go @@ -25,7 +25,7 @@ func TestPetStore(t *testing.T) { var err error // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // Clear out the servers array in the swagger spec, that skips validating diff --git a/examples/petstore-expanded/strict/api/petstore-server.gen.go b/examples/petstore-expanded/strict/api/petstore-server.gen.go index 4877d1d564..e35edad725 100644 --- a/examples/petstore-expanded/strict/api/petstore-server.gen.go +++ b/examples/petstore-expanded/strict/api/petstore-server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -619,54 +619,55 @@ func (sh *strictHandler) FindPetByID(w http.ResponseWriter, r *http.Request, id } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+RXW48budH9KwV+32OnNbEXedBTvB4vICBrT+LdvKznoYZdkmrBSw9Z1FgY6L8HRbZu", - "I3k2QYIgQV506WY1T51zqlj9bGz0YwwUJJv5s8l2TR7rzw8pxaQ/xhRHSsJUL9s4kH4PlG3iUTgGM2+L", - "od7rzDImj2LmhoO8fWM6I9uR2l9aUTK7znjKGVfffND+9iE0S+KwMrtdZxI9Fk40mPkvZtpwv/x+15mP", - "9HRHcok7oL+y3Uf0BHEJsiYYSS437Izg6jLup+34etwLoHV3hTdhQ+c+Lc38l2fz/4mWZm7+b3YUYjap", - "MJty2XUvk+HhEtLPgR8LAQ/nuE7F+MN3V8R4gZQHc7+73+llDsvYJA+CtuImj+zM3ODIQuj/mJ9wtaLU", - "czTdRLH53K7Bu7sF/EToTWdK0qC1yJjns9lJ0K57kcU7yOhHRzVa1ihQMmVAzSZLTASYAQPQ17ZMIgzk", - "Y8iSUAiWhFISZeBQOfg0UtAnve1vII9keckW61adcWwpZDqaw7wb0a4J3vQ3F5ifnp56rLf7mFazKTbP", - "/rR4/+Hj5w+/e9Pf9GvxrjqGks+flp8pbdjS1cRndc1M5WBxp6zdTXmazmwo5cbK7/ub/kYfHUcKOLKZ", - "m7f1UmdGlHX1xEwZ0h+rZrFzXv9CUlLIgM5VKmGZoq8U5W0W8o1r/V8yJVgry9ZSziDxS/iIHjINYGMY", - "2FOQ4oGy9PAjkqWAGYT8GBNkXLEIZ8g4MoUOAllI6xhsyZDJnyxgAfQkPbyjQBgABVYJNzwgYFkV6gAt", - "MNriuIb28L4kfGApCeLAEVxM5DuIKWAioBUJkKMJXSDbgS0pl6wl4chKyT3cFs7gGaSkkXMHY3EbDph0", - "L0pRk+5AOFgeShDYYOKS4deSJfawCLBGC2sFgTkTjA6FEAa2UrzSsWhFpbngwCNny2EFGESzOebueFUc", - "HjIf15hIEu5J1PXgo6MsTMB+pDSwMvVX3qBvCaHjx4IeBkZlJmGGR81tQ44FQgwgMUlMSgkvKQyH3Xu4", - "S0iZgihMCuyPAEoKCJvoiowosKFAARVwI1c/PJakz1iE45OXlCbWl2jZcT7bpO6gH91RXws5DuhIhR06", - "5dFSQtHE9LuHzyWPFAZWlh2qeYboYurUgZmsqJtrltUqmnUHG1qzLQ5BW1saigfHD5RiDz/G9MBAhbOP", - "w6kMersa26HlwNh/CV/CZxqqEiXDktR8Lj7EVAMoHh2TiqTie9Da8FgfOJHP2XVA5axamuTgivpQ3dnD", - "3RozOdcKY6Q0hVeaq7wksMRi+aE0wnG/j647jd+Qm6TjDaWE3fnWWifAQ3coxMAP6x5+FhjJOQpCWU+O", - "MeZCWkn7IupBqcB9FWjR7bncP2mfVmWyq0AOtgglWJDEWerBtGFB6uGHki0BSe0GQ+FDFWinyJYcJa5w", - "mn/3AV7dUrCaxxafMYDHlaZMblKrhz+XFuqjU92aelSad45QukPzASxWi6StnOzZ0p7MMTWZQzWqWVRg", - "4NAdoUyFGzjzHnBWDJalDKxQc0YosvfZJGTb6Yy0ul8Pd6fCVOYmjGMi4eJPOlczTelO/K2tt/+iZ5wO", - "DfW8Wwxmbn7gMOj5Uo+NpARQynUKOT8sBFfa92HJTijBw9boMGDm5rFQ2h5Pel1numlorHOJkK9n0OUU", - "1S5gSrjV/1m29djT8aQOOOcIPH5lr228+AdKOtEkysVJhZXqWfYNTI49yxmo3xxHd/c6AuVRW0tF/+bm", - "Zj/3UGjz2ji6aXKY/ZoV4vO1tF8b5tok94KI3cUANJLAHkwbj5ZYnPxDeF6D0cb6KxuXQF9Hba3ag9ua", - "zuTiPabtlQFCsY0xXxk13idCqTNboCddux/G6lyjZ3DDrkt0nnMuPtFwYdZ3g3rVtOmUsnwfh+2/jIX9", - "ZH1Jwx2JegyHQb8OsM3plCyp0O6f9MxvWuW/xxoXgtf7dR6dPfOwaxZxJFdewNp1jc0cVq6+tcADapuN", - "zTWLW8hFc7rikdsa3Wzyakdb3GoPGZu2E5apf+gAfWwfPFwo/a1ecv1t6rKXfHeZtQJpKIb/JCFvD2JU", - "FbawuFV4r79QnCt20HFx+63j5/ttvff367Ukset/m1z/s2X8QtGmfl1CabOX6fyteP9S3p+82err6e5+", - "97cAAAD//ykDnxlaEgAA", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "5Fdbjxu50f0rBX7fY6c1sRd50FO8Hi8gIGtP4t28rOehhl2SasFLD1nUWBjovwdFtm4jeTZBgiBBXnTp", + "ZjVPnXOqWP1sbPRjDBQkm/mzyXZNHuvPDynFpD/GFEdKwlQv2ziQfg+UbeJROAYzb4uh3uvMMiaPYuaG", + "g7x9Yzoj25HaX1pRMrvOeMoZV9980P72ITRL4rAyu11nEj0WTjSY+S9m2nC//H7XmY/0dEdyiTugv7Ld", + "R/QEcQmyJhhJLjfsjODqMu6n7fh63AugdXeFN2FD5z4tzfyXZ/P/iZZmbv5vdhRiNqkwm3LZdS+T4eES", + "0s+BHwsBD+e4TsX4w3dXxHiBlAdzv7vf6WUOy9gkD4K24iaP7Mzc4MhC6P+Yn3C1otRzNN1EsfncrsG7", + "uwX8ROhNZ0rSoLXImOez2UnQrnuRxTvI6EdHNVrWKFAyZUDNJktMBJgBA9DXtkwiDORjyJJQCJaEUhJl", + "4FA5+DRS0Ce97W8gj2R5yRbrVp1xbClkOprDvBvRrgne9DcXmJ+ennqst/uYVrMpNs/+tHj/4ePnD797", + "09/0a/GuOoaSz5+Wnylt2NLVxGd1zUzlYHGnrN1NeZrObCjlxsrv+5v+Rh8dRwo4spmbt/VSZ0aUdfXE", + "TBnSH6tmsXNe/0JSUsiAzlUqYZmirxTlbRbyjWv9XzIlWCvL1lLOIPFL+IgeMg1gYxjYU5DigbL08COS", + "pYAZhPwYE2RcsQhnyDgyhQ4CWUjrGGzJkMmfLGAB9CQ9vKNAGAAFVgk3PCBgWRXqAC0w2uK4hvbwviR8", + "YCkJ4sARXEzkO4gpYCKgFQmQowldINuBLSmXrCXhyErJPdwWzuAZpKSRcwdjcRsOmHQvSlGT7kA4WB5K", + "ENhg4pLh15Il9rAIsEYLawWBOROMDoUQBrZSvNKxaEWlueDAI2fLYQUYRLM55u54VRweMh/XmEgS7knU", + "9eCjoyxMwH6kNLAy9VfeoG8JoePHgh4GRmUmYYZHzW1DjgVCDCAxSUxKCS8pDIfde7hLSJmCKEwK7I8A", + "SgoIm+iKjCiwoUABFXAjVz88lqTPWITjk5eUJtaXaNlxPtuk7qAf3VFfCzkO6EiFHTrl0VJC0cT0u4fP", + "JY8UBlaWHap5huhi6tSBmayom2uW1SqadQcbWrMtDkFbWxqKB8cPlGIPP8b0wECFs4/DqQx6uxrboeXA", + "2H8JX8JnGqoSJcOS1HwuPsRUAygeHZOKpOJ70NrwWB84kc/ZdUDlrFqa5OCK+lDd2cPdGjM51wpjpDSF", + "V5qrvCSwxGL5oTTCcb+PrjuN35CbpOMNpYTd+dZaJ8BDdyjEwA/rHn4WGMk5CkJZT44x5kJaSfsi6kGp", + "wH0VaNHtudw/aZ9WZbKrQA62CCVYkMRZ6sG0YUHq4YeSLQFJ7QZD4UMVaKfIlhwlrnCaf/cBXt1SsJrH", + "Fp8xgMeVpkxuUquHP5cW6qNT3Zp6VJp3jlC6Q/MBLFaLpK2c7NnSnswxNZlDNapZVGDg0B2hTIUbOPMe", + "cFYMlqUMrFBzRiiy99kkZNvpjLS6Xw93p8JU5iaMYyLh4k86VzNN6U78ra23/6JnnA4N9bxbDGZufuAw", + "6PlSj42kBFDKdQo5PywEV9r3YclOKMHD1ugwYObmsVDaHk96XWe6aWisc4mQr2fQ5RTVLmBKuNX/Wbb1", + "2NPxpA445wg8fmWvbbz4B0o60STKxUmFlepZ9g1Mjj3LGajfHEd39zoC5VFbS0X/5uZmP/dQaPPaOLpp", + "cpj9mhXi87W0Xxvm2iT3gojdxQA0ksAeTBuPllic/EN4XoPRxvorG5dAX0dtrdqD25rO5OI9pu2VAUKx", + "jTFfGTXeJ0KpM1ugJ127H8bqXKNncMOuS3Secy4+0XBh1neDetW06ZSyfB+H7b+Mhf1kfUnDHYl6DIdB", + "vw6wzemULKnQ7p/0zG9a5b/HGheC1/t1Hp0987BrFnEkV17A2nWNzRxWrr61wANqm43NNYtbyEVzuuKR", + "2xrdbPJqR1vcag8Zm7YTlql/6AB9bB88XCj9rV5y/W3qspd8d5m1Amkohv8kIW8PYlQVtrC4VXivv1Cc", + "K3bQcXH7rePn+2299/frtSSx63+bXP+zZfxC0aZ+XUJps5fp/K14/1Len7zZ6uvp7n73twAAAP//", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -674,7 +675,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -692,12 +693,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -723,3 +724,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/examples/petstore-expanded/strict/petstore.go b/examples/petstore-expanded/strict/petstore.go index 363caf7e1a..e7dc41a97f 100644 --- a/examples/petstore-expanded/strict/petstore.go +++ b/examples/petstore-expanded/strict/petstore.go @@ -21,7 +21,7 @@ func main() { port := flag.String("port", "8080", "Port for test HTTP server") flag.Parse() - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) os.Exit(1) diff --git a/examples/petstore-expanded/strict/petstore_test.go b/examples/petstore-expanded/strict/petstore_test.go index 208b65ea3e..1ec6a76ea4 100644 --- a/examples/petstore-expanded/strict/petstore_test.go +++ b/examples/petstore-expanded/strict/petstore_test.go @@ -24,7 +24,7 @@ func TestPetStore(t *testing.T) { var err error // Get the swagger description of our API - swagger, err := api.GetSwagger() + swagger, err := api.GetSpec() require.NoError(t, err) // Clear out the servers array in the swagger spec, that skips validating diff --git a/examples/streaming/stdhttp/sse/streaming.gen.go b/examples/streaming/stdhttp/sse/streaming.gen.go index 94aa81e3e4..cd2a15e01c 100644 --- a/examples/streaming/stdhttp/sse/streaming.gen.go +++ b/examples/streaming/stdhttp/sse/streaming.gen.go @@ -7,7 +7,7 @@ package sse import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -285,33 +285,34 @@ func (sh *strictHandler) GetStream(w http.ResponseWriter, r *http.Request) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/2SSQW/bMAyF/wrB0wY4qZzc9AeGDcU2wD3tptpMwsKiNIkJVhT+7wPlLV2yi2VQeO97", - "fNAbshwS+jdU1pnQ48AxzwRfhm9fH2HQQiGyHGGgcuGRsMMLlcpJ0GO/dVuHS4cpk4TM6HHfRh3moKdq", - "tg/2OZLaMVEdC2dd1d9LuvBEFQLUhoF0aFiY0niOJFrhQxKCTAVmFuog5DzzGMzg4aUmmT/CmEQDi0UM", - "oBypaogZgkxQ6eeZZCSQc3ymssUWtDT55wk9fiJdF8QOC9WcpFILvXPODvMmadH/I9uQfgXryn7/stD3", - "HVoM9Lhzu/2m7zc799Q7v3feuR/WVh1PFIOpcrFAyiv13eO+quF2EytKTwR0IVFbS1+zAVmUjlSMsUa4", - "93m69nPvcEglBkWPU1DaNPXVtmphOeKyXCfp+YVGxcVGt4R/n01T1HOMobz+uYJHFqrv98vyOwAA///z", - "FQ4NgQIAAA==", + "ZJJBb9swDIX/CsHTBjipnNz0B4YNxTbAPe2m2kzCwqI0iQlWFP7vA+UtXbKLZVB473t80BuyHBL6N1TW", + "mdDjwDHPBF+Gb18fYdBCIbIcYaBy4ZGwwwuVyknQY791W4dLhymThMzocd9GHeagp2q2D/Y5ktoxUR0L", + "Z13V30u68EQVAtSGgXRoWJjSeI4kWuFDEoJMBWYW6iDkPPMYzODhpSaZP8KYRAOLRQygHKlqiBmCTFDp", + "55lkJJBzfKayxRa0NPnnCT1+Il0XxA4L1ZykUgu9c84O8yZp0f8j25B+BevKfv+y0PcdWgz0uHO7/abv", + "Nzv31Du/d965H9ZWHU8Ug6lysUDKK/Xd476q4XYTK0pPBHQhUVtLX7MBWZSOVIyxRrj3ebr2c+9wSCUG", + "RY9TUNo09dW2amE54rJcJ+n5hUbFxUa3hH+fTVPUc4yhvP65gkcWqu/3y/I7AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -319,7 +320,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -337,12 +338,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -368,3 +369,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/all_of/v1/openapi.gen.go b/internal/test/all_of/v1/openapi.gen.go index db5fd302cd..46571fcce3 100644 --- a/internal/test/all_of/v1/openapi.gen.go +++ b/internal/test/all_of/v1/openapi.gen.go @@ -5,7 +5,7 @@ package v1 import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -38,37 +38,39 @@ type PersonWithID struct { ID int64 `json:"ID"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5SUT2/bOBDFv8qAu0dBTrCLPegWrNtAQJEaaNIc4gAZSyOLKTVkyVEMwfB3L0jJ/+AW", - "aX0awOTjvDe/0VZVtnOWiSWoYqtC1VKHqVyQD5ZjhcZ8blTxtFV/e2pUof6aHW/Npiuz8fzCW0deNAW1", - "y7bK0/dee6pV8aQ+ah/kDjtSmfqEU/m8e85UTaHy2omO76n7VgfQARBcksxgo6WFDrlGsX6AJgoBcg0G", - "gwBjRxmsegGbJNBAOV8y992KfA5JbmN7U8OKwJP0nqmG1QAIL7ckLxBkMAQ3izKHR4KO/JpAWpqeX7I7", - "eBo7QbbSkocvyTlsWl21YNkM4Lx90zUF2PuGRpOpQ75klSkZHKlC2dUrVaJ2mbqIrNheZEGBAD1NQiAt", - "CgRHlW6GQ0LRJA3pGBpziCGLGS354L0Pk2+Glw+1PnUOxLWzmiWDTUuegLBq4xD2WqMDd9bqcaDFdm8u", - "iNe8juZu7Rt57oilnN+lWcRjjfUdiiqUZvnv32MomoXW5OPFAxuXqrtfhviopS3nf0prYvTc1Cjybpu7", - "7Iztcv47JIOnyvoaMBw5bLztAOF/Tyh0GEMOpUBlWVBzWHKcaiRygsA2gLA4XQ5kwLrWE/6egu19RfDw", - "UM5/yl7sX3NjU8ZaTPzvnoIEuInxQUosJD2VqTfyYXR0nV/lVzF164jRaVWof/Kr/DqygdKmBGfOYEWt", - "NfU48jXJJdhf0ei0zgE2yAIoYChus2WCKJVBsCAxwA6/UQSfOmjRuWE0FGeGUaysVaEWJ0/GyQRnOewX", - "qsHepBZioMSpROeMrpLA7HX6zo1sxOp9cibeUpDnzk7d79LvRwAAAP//lzc18GUFAAA=", + "lJRPb9s4EMW/yoC7R0FOsIs96Bas20BAkRpo0hziABlLI4spNWTJUQzB8HcvSMn/4BZpfRrA5OO8N7/R", + "VlW2c5aJJahiq0LVUoepXJAPlmOFxnxuVPG0VX97alSh/podb82mK7Px/MJbR140BbXLtsrT9157qlXx", + "pD5qH+QOO1KZ+oRT+bx7zlRNofLaiY7vqftWB9ABEFySzGCjpYUOuUaxfoAmCgFyDQaDAGNHGax6AZsk", + "0EA5XzL33Yp8DkluY3tTw4rAk/SeqYbVAAgvtyQvEGQwBDeLModHgo78mkBamp5fsjt4GjtBttKShy/J", + "OWxaXbVg2QzgvH3TNQXY+4ZGk6lDvmSVKRkcqULZ1StVonaZuois2F5kQYEAPU1CIC0KBEeVboZDQtEk", + "DekYGnOIIYsZLfngvQ+Tb4aXD7U+dQ7EtbOaJYNNS56AsGrjEPZaowN31upxoMV2by6I17yO5m7tG3nu", + "iKWc36VZxGON9R2KKpRm+e/fYyiahdbk48UDG5equ1+G+KilLed/Smti9NzUKPJum7vsjO1y/jskg6fK", + "+howHDlsvO0A4X9PKHQYQw6lQGVZUHNYcpxqJHKCwDaAsDhdDmTAutYT/p6C7X1F8PBQzn/KXuxfc2NT", + "xlpM/O+eggS4ifFBSiwkPZWpN/JhdHSdX+VXMXXriNFpVah/8qv8OrKB0qYEZ85gRa019TjyNckl2F/R", + "6LTOATbIAihgKG6zZYIolUGwIDHADr9RBJ86aNG5YTQUZ4ZRrKxVoRYnT8bJBGc57Beqwd6kFmKgxKlE", + "54yuksDsdfrOjWzE6n1yJt5SkOfOTt3v0u9HAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -76,7 +78,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -94,12 +96,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -125,3 +127,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/all_of/v2/openapi.gen.go b/internal/test/all_of/v2/openapi.gen.go index ab430340d6..b25d5bb90a 100644 --- a/internal/test/all_of/v2/openapi.gen.go +++ b/internal/test/all_of/v2/openapi.gen.go @@ -5,7 +5,7 @@ package v2 import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -38,37 +38,39 @@ type PersonWithID struct { LastName string `json:"LastName"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5SUT2/bOBDFv8qAu0dBTrCLPegWrNtAQJEaaNIc4gAZSyOLKTVkyVEMwfB3L0jJ/+AW", - "aX0awOTjvDe/0VZVtnOWiSWoYqtC1VKHqVyQD5ZjhcZ8blTxtFV/e2pUof6aHW/Npiuz8fzCW0deNAW1", - "y7bK0/dee6pV8aQ+ah/kDjtSmfqEU/m8e85UTaHy2omO76n7VgfQARBcksxgo6WFDrlGsX6AJgoBcg0G", - "gwBjRxmsegGbJNBAOV8y992KfA5JbmN7U8OKwJP0nqmG1QAIL7ckLxBkMAQ3izKHR4KO/JpAWpqeX7I7", - "eBo7QbbSkocvyTlsWl21YNkM4Lx90zUF2PuGRpOpQ75klSkZHKlC2dUrVaJ2mbqIrNheZEGBAD1NQiAt", - "CgRHlW6GQ0LRJA3pGBpziCGLGS354L0Pk2+Glw+1PnUOxLWzmiWDTUuegLBq4xD2WqMDd9bqcaDFdm8u", - "iNe8juZu7Rt57oilnN+lWcRjjfUdiiqUZvnv32MomoXW5OPFAxuXqrtfhviopS3nf0prYvTc1Cjybpu7", - "7Iztcv47JIOnyvoaMBw5bLztAOF/Tyh0GEMOpUBlWVBzWHKcaiRygsA2gLA4XQ5kwLrWE/6egu19RfDw", - "UM5/yl7sX3NjU8ZaTPzvnoIEuInxQUosJD2VqTfyYXR0nV/lVzF164jRaVWof/Kr/DqygdKmBGfOYEWt", - "NfU48jXJJdhf0ei0zgE2yAIoYChus2WCKJVBsCAxwA6/UQSfOmjRuWE0FGeGUaysVaEWJ0/GyQRnOewX", - "qsHepBZioMSpROeMrpLA7HX6zo1sxOp9cibeUpDnzk7d79LvRwAAAP//lzc18GUFAAA=", + "lJRPb9s4EMW/yoC7R0FOsIs96Bas20BAkRpo0hziABlLI4spNWTJUQzB8HcvSMn/4BZpfRrA5OO8N7/R", + "VlW2c5aJJahiq0LVUoepXJAPlmOFxnxuVPG0VX97alSh/podb82mK7Px/MJbR140BbXLtsrT9157qlXx", + "pD5qH+QOO1KZ+oRT+bx7zlRNofLaiY7vqftWB9ABEFySzGCjpYUOuUaxfoAmCgFyDQaDAGNHGax6AZsk", + "0EA5XzL33Yp8DkluY3tTw4rAk/SeqYbVAAgvtyQvEGQwBDeLModHgo78mkBamp5fsjt4GjtBttKShy/J", + "OWxaXbVg2QzgvH3TNQXY+4ZGk6lDvmSVKRkcqULZ1StVonaZuois2F5kQYEAPU1CIC0KBEeVboZDQtEk", + "DekYGnOIIYsZLfngvQ+Tb4aXD7U+dQ7EtbOaJYNNS56AsGrjEPZaowN31upxoMV2by6I17yO5m7tG3nu", + "iKWc36VZxGON9R2KKpRm+e/fYyiahdbk48UDG5equ1+G+KilLed/Smti9NzUKPJum7vsjO1y/jskg6fK", + "+howHDlsvO0A4X9PKHQYQw6lQGVZUHNYcpxqJHKCwDaAsDhdDmTAutYT/p6C7X1F8PBQzn/KXuxfc2NT", + "xlpM/O+eggS4ifFBSiwkPZWpN/JhdHSdX+VXMXXriNFpVah/8qv8OrKB0qYEZ85gRa019TjyNckl2F/R", + "6LTOATbIAihgKG6zZYIolUGwIDHADr9RBJ86aNG5YTQUZ4ZRrKxVoRYnT8bJBGc57Beqwd6kFmKgxKlE", + "54yuksDsdfrOjWzE6n1yJt5SkOfOTt3v0u9HAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -76,7 +78,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -94,12 +96,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -125,3 +127,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec.gen.go b/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec.gen.go index 030c8277d9..f11ee94195 100644 --- a/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec.gen.go +++ b/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec.gen.go @@ -5,7 +5,7 @@ package preserveoriginaloperationidcasinginembeddedspec import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -15,30 +15,32 @@ import ( "github.com/getkin/kin-openapi/openapi3" ) -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/7SOwUrFQAxFf0Xuevpe1d3sHuJCBBH8AJnXxjbaZkIThFLm32XGlR9gNjcEcu45wPKR", - "EQ84+0KIWPcbUxoQ8E2bcRZE3J76U48SkJUkKSPivp0CNPls9f+s5DVHWsipbllpS85ZnkZE+MzWsXWp", - "+6Jrul5kfEgrLe9vL5fnRwRsZJrFqMHu+r7GkMVJGjapLjw03PnTqtUBG2ZaU5PftbqbbywTSpuA6dfo", - "r8dE/kr+H4WllJ8AAAD//+CJBDdPAQAA", + "tI7BSsVADEV/Re56+l7V3ewe4kIEEfwAmdfGNtpmQhOEUubfZcaVH2A2NwRy7jnA8pERDzj7QohY9xtT", + "GhDwTZtxFkTcnvpTjxKQlSQpI+K+nQI0+Wz1/6zkNUdayKluWWlLzlmeRkT4zNaxdan7omu6XmR8SCst", + "728vl+dHBGxkmsWowe76vsaQxUkaNqkuPDTc+dOq1QEbZlpTk9+1uptvLBNKm4Dp1+ivx0T+Sv4fhaWU", + "nwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -46,7 +48,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -64,12 +66,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -95,3 +97,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go b/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go index 2f395b5776..01b7f91c59 100644 --- a/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go +++ b/internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go @@ -9,7 +9,7 @@ import ( ) func TestSpecReturnsOperationIdAsOriginallySpecified(t *testing.T) { - spec, err := GetSwagger() + spec, err := GetSpec() require.NoError(t, err) path := spec.Paths.Find("/pet") diff --git a/internal/test/externalref/externalref.gen.go b/internal/test/externalref/externalref.gen.go index 158a922d02..82f42dfbbd 100644 --- a/internal/test/externalref/externalref.gen.go +++ b/internal/test/externalref/externalref.gen.go @@ -5,7 +5,7 @@ package externalref import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -26,34 +26,36 @@ type Container struct { Pet *externalRef1.Pet `json:"pet,omitempty"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6RUTW/bMAz9KwG3o9Bk6LCDb213Xw7bqSgMRmYcbbakSUzWoNB/Hyg1jROnSLJdDJof", - "D+890n4B7XrvLFmOUL1A1CvqMYcPzjIaS0FefHCeAhvKJbf4SZprlPhjoCVU8GG6B5q+okw96l/Y0l0d", - "Pen6W566g6R2AIsLAe6HAPcDAH0O4K0vKfDE59rRm3pzWztPVsI5MaSUFBzlH5CpdWE7dsY08qRn7H1H", - "UH1SsHShR4YKjOUvn0EBbz2VV2opCDGLPR2MwVfXxn1r5GBsC0LkNVNkgYLnvpPJggB6x+sE53lRf0hX", - "D4Rc4cub/qRGimf/KLlxbWtoLFqBXzl2P0JXDGbqc3DYduzEbmZoGoaA233nn4DeUwMVhzVJW2TkdcZu", - "KOpgPBtnBYt4UmoTYye8oklkF4Qq2XUP1SPgBk2Hi05ynmxTGEXXNfB0QhBje6jlCuu/Y4G4RFJSEOj3", - "2gRJPRZrhnY+nbsnn+9/dErC4Z3Lv2L11x43Y+kafvrYNEa2hN18QEbUH6PJHZ38G42EvMPvv39aaU/h", - "qHQphZQxjF26XDScPxxQsKEQy61mnmVNUMHtzexmJitHXglwSn8DAAD//xIv2MTwBQAA", + "pFRNb9swDP0rAbej0GTosINvbXdfDtupKAxGZhxttqRJTNag0H8fKDWNE6dIsl0Mmh8P7z3SfgHteu8s", + "WY5QvUDUK+oxhw/OMhpLQV58cJ4CG8olt/hJmmuU+GOgJVTwYboHmr6iTD3qX9jSXR096fpbnrqDpHYA", + "iwsB7ocA9wMAfQ7grS8p8MTn2tGbenNbO09WwjkxpJQUHOUfkKl1YTt2xjTypGfsfUdQfVKwdKFHhgqM", + "5S+fQQFvPZVXaikIMYs9HYzBV9fGfWvkYGwLQuQ1U2SBgue+k8mCAHrH6wTneVF/SFcPhFzhy5v+pEaK", + "Z/8ouXFta2gsWoFfOXY/QlcMZupzcNh27MRuZmgahoDbfeefgN5TAxWHNUlbZOR1xm4o6mA8G2cFi3hS", + "ahNjJ7yiSWQXhCrZdQ/VI+AGTYeLTnKebFMYRdc18HRCEGN7qOUK679jgbhEUlIQ6PfaBEk9FmuGdj6d", + "uyef7390SsLhncu/YvXXHjdj6Rp++tg0RraE3XxARtQfo8kdnfwbjYS8w++/f1ppT+GodCmFlDGMXbpc", + "NJw/HFCwoRDLrWaeZU1Qwe3N7GYmK0deCXBKfwMAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -61,7 +63,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -97,12 +99,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -128,3 +130,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/externalref/imports_test.go b/internal/test/externalref/imports_test.go index 34fd0ec11e..7b84c6d0ef 100644 --- a/internal/test/externalref/imports_test.go +++ b/internal/test/externalref/imports_test.go @@ -18,15 +18,15 @@ func TestParameters(t *testing.T) { } func TestGetSwagger(t *testing.T) { - _, err := packageB.GetSwagger() + _, err := packageB.GetSpec() require.Nil(t, err) - _, err = packageA.GetSwagger() + _, err = packageA.GetSpec() require.Nil(t, err) - _, err = petstore.GetSwagger() + _, err = petstore.GetSpec() require.Nil(t, err) - _, err = GetSwagger() + _, err = GetSpec() require.Nil(t, err) } diff --git a/internal/test/externalref/packageA/externalref.gen.go b/internal/test/externalref/packageA/externalref.gen.go index a859c18af1..1738872708 100644 --- a/internal/test/externalref/packageA/externalref.gen.go +++ b/internal/test/externalref/packageA/externalref.gen.go @@ -5,7 +5,7 @@ package packagea import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -36,32 +36,34 @@ type StatusPostPayload struct { Status externalRef0.StatusEnum `json:"status"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5xTzW7CMAx+F2/HSIhrbkPiDNo0LghVJnEhW5pkSToNVXn3KaEIKjqp7GbX9tfvp+1A", - "2MZZQyYG4B0EcaQGS7k0XokjyfdAPveo9aoGvu3g2VMNHJ5m19tZfzhzKD7xQIsqOBJVuU2sA+etIx8V", - "FWj6iR6rWpGWuY0nR8AhRK/MAVJilyd2/0EiQtolBqtSv+T9IZjBhkZQWH9d7fNwOuXzexaQMo+3iLEN", - "axviGk/aovyvEWegzXzEDE8YrJnswzjbqa6kO4RXq8simbYBvgWUjTLAoM3R7di9rWPCluX4BkRE9U3A", - "QJm+nIq0mQ8tHqoKZeexQG8YZvWevlrlSWaaPdxugtGXv2DIR8nRL89b3c8jNQ/SLXlco0fv8ZT7nMdf", - "oQ5VKQk36/fi8r4ytQVuWq0ZWEcGnQIOkFXHYzhP0m8AAAD//1KVtScdBAAA", + "nFPNbsIwDH4Xb8dIiGtuQ+IM2jQuCFUmcSFbmmRJOg1VefcpoQgqOqnsZtf21++n7UDYxllDJgbgHQRx", + "pAZLuTReiSPJ90A+96j1qga+7eDZUw0cnmbX21l/OHMoPvFAiyo4ElW5TawD560jHxUVaPqJHqtakZa5", + "jSdHwCFEr8wBUmKXJ3b/QSJC2iUGq1K/5P0hmMGGRlBYf13t83A65fN7FpAyj7eIsQ1rG+IaT9qi/K8R", + "Z6DNfMQMTxismezDONuprqQ7hFeryyKZtgG+BZSNMsCgzdHt2L2tY8KW5fgGRET1TcBAmb6cirSZDy0e", + "qgpl57FAbxhm9Z6+WuVJZpo93G6C0Ze/YMhHydEvz1vdzyM1D9IteVyjR+/xlPucx1+hDlUpCTfr9+Ly", + "vjK1BW5arRlYRwadAg6QVcdjOE/SbwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -69,7 +71,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -93,12 +95,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -124,3 +126,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/externalref/packageB/externalref.gen.go b/internal/test/externalref/packageB/externalref.gen.go index 8b07f571c9..c02df37aac 100644 --- a/internal/test/externalref/packageB/externalref.gen.go +++ b/internal/test/externalref/packageB/externalref.gen.go @@ -5,7 +5,7 @@ package packageb import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -74,31 +74,32 @@ type User struct { Username string `json:"username"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RRTUvDQBT8L6PHheB1j4LngqKX0sOavNiV/XL3rVDK/nd5a7CxtXjKhJnJm5kcMUaf", - "YqDABfqIMu7Jmw43r+808r3AlGOizJY6EYwnefIhETQKZxve0FpTeIyuUxSqh97CTN4GKNRCGTt1blF4", - "YsO1PHT5yjay/SQo2LDA696XO3Ea5zYz9PY8a+kaQbeZZmjcDKfCw9J2WKWQFpk+qs00SZTlA6f7sc+C", - "tmsKz1LrYh87/bGOQo5u4Zn8v5H6ku3nqsnZHORdlrz2A34ntxNW8ssCordhjtChOqcQEwWTLDSgkAzv", - "yzfTvgIAAP//mT+m2CQCAAA=", + "hFFNS8NAFPwvo8eF4HWPgueCopfSw5q82JX9cvetUMr+d3lrsLG1eMqEmcmbmRwxRp9ioMAF+ogy7smb", + "Djev7zTyvcCUY6LMljoRjCd58iERNApnG97QWlN4jK5TFKqH3sJM3gYo1EIZO3VuUXhiw7U8dPnKNrL9", + "JCjYsMDr3pc7cRrnNjP09jxr6RpBt5lmaNwMp8LD0nZYpZAWmT6qzTRJlOUDp/uxz4K2awrPUutiHzv9", + "sY5Cjm7hmfy/kfqS7eeqydkc5F2WvPYDfie3E1byywKit2GO0KE6pxATBZMsNKCQDO/LN9O+AgAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -106,7 +107,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -124,12 +125,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -155,3 +156,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/externalref/petstore/externalref.gen.go b/internal/test/externalref/petstore/externalref.gen.go index e4b540a404..d70f4bec71 100644 --- a/internal/test/externalref/petstore/externalref.gen.go +++ b/internal/test/externalref/petstore/externalref.gen.go @@ -5,7 +5,7 @@ package packagea import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -252,78 +252,80 @@ type UpdateUserJSONRequestBody = User // UpdateUserFormdataRequestBody defines body for UpdateUser for application/x-www-form-urlencoded ContentType. type UpdateUserFormdataRequestBody = User -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xb/2/jNrL/V/jUB/QVcCwn2b69Gjig2c22yF26GzS7dz0kQUFLY4ldiVRJyo4b5H8/", - "DEnJ+mrLTpy7ot0fdrUSyRnOfOYr6QcvEGkmOHCtvOmDJ+HXHJR+I0IG5sUVaPwnEFwDN480yxIWUM0E", - "939RguM7FcSQUnz6Xwlzb+p94a/X9e1X5eNaj4+j2gr3abLrAo8jLwQVSJbhCt4UeSRi9gsEmuiYasIB", - "QkW0IDMgNAwhxGcdA1FaSPAeR94nBfJMSrraaW9MQ6q28YhLIwm9ysCbetRQ6WD6kilNxJzkCqTj3gjH", - "rYNkzsJQgjKPmRQZSO2UEjBtOId7mmYJkrmiiSBniRZeSVlpyXiErChNNdTHvz3rHijB6ns98tXpa3K5", - "0lrwrhm/saw+/JtXp5Pj9si1QNxWR57TPKepkZPbK448y9iPoDLBFXTsXYTm7VzIlGpv6jGuT0/WFBnX", - "EFkVpKAUjczoFuP2xcPOfH7xRQhzmidWWW+phkjIVZtNFtbkcjyqMfz/rzoZtjSq4jwXkdpDmkHBl2Ey", - "V1qkINtM0jXABmG7AGQT3j3KBGR9KWmWQehNtcwB2WlKZoJ/BokHTaUtojnEUb7aR0iFXHDoBxl2SQiF", - "kICuQmUmRAKUe11bGbSNDPRFY+I3f3n9+mTQ5F9zynXT/F+PhpiDill27jxBOTykGo40S6HPceRGDnXf", - "ZYRFru3XkQc8T73pjZclNIDQMw5eioV5DCFhC5AQenejitIqI3ZVmzCawnEuNjU0VjHJTVguTXdvPbah", - "GIooYp2SzGKhxSeZ1G2tPqy50WJOVSYNe2sZV5/GMtDEfiOMV2LhWnl0QVlCZwm+y4CHliMlEqO5tv+k", - "0XC/8ZFG3tA9PI5MEsIQMtMbK4uq/O624SNzWQYS7XHLOyh3V3RqakeZNKBFHlLKkjpmfhEx/9a8Hwci", - "7cLOnEml37fA9jcRd4bk/cCc0E4aNAXViWeq1FLIOinv+OT01dc98OcwcCx6+eseGKNUK36nJ7r2+L/u", - "8KFjMLra3RHlJtMzVgdBLpleXSPeXWjN2M+fwXghhpzHQENDpQiR7vvaKjL2d1i5+GCM82ea69jANRFL", - "i94U01NmU9Vcx0Ky30yyil5i6sVaZ2rq+8UCp2O1pFEEcsyEL3CCX8xCm1KByMBl/TSc4ixvap7JSuSS", - "mBcYwJmG4msqQjZfmU/oSMw4GgQi5y4zL0SGhE7sK7jXKPjkXAQdKv2O8ZCIXJNUSCB0ho/Xlm1v5OXl", - "xqa+v96NwTmfiyJ9p4GumBfKUgNNv61PqNP9GDNFmCKUKAMFglXENYqNXINcgCQzqiAkwrrLDxnws6sL", - "cjqeEJVBwOauThgT8i+Rk4ByMm9v5Za7vRCqyU1rH3f/13r11ZhcWJI6ZjIkTIM0hLBYwNfWlQsJI7KE", - "LxdA1JLpIF5XOSEoFiE3UmliAi0N4v+55QWbXCxJDElGMBikJg6bebi9ZQw6BkmY/lKR2Yqk9DPjEQli", - "yiNQawpzxplhimkFyZwIWXzD/Hx8yz9iIbakqxFZMh0TzDCQX8NAkyjjJAIOkiYjQnlI4D4TCogSKRSb", - "5rAkc6A6l2CA9+Hs+nR8y2/5NQ7KFczzhCSMf1bTW35Ebj7GVYVKyIRiWsiVFTgaScR0nM/Q5xbCP6IZ", - "K58LG/qqXE6JXAaW4cr+57jzKrGdKfizRMz8lCoN0lcy8FPKuC/B0lO+yIDTjI1XNE2+8kZewgJwlZHz", - "JWcZDWIgJ+NJ02KWy+WYmq9jISPfTVX+5cXbd++v3x2djCfjWKeJic4gU/VhjuBnAXRZnW+G+OizmDbO", - "swD3ldsLOaoaijfyFiCVtbfj8WR8/BoJuQ15U+90PBmjr86ojo1rQNdloqZQuu0qzsKQUAMFtIFaTW9W", - "tXaCuTUOxexwVGlorA7bxzhaLpdHGIWOcpkARzMI//OtkbcSqIaK1BrZ3zrVMtkXvrCFt1HHyWTyX9/8", - "uc6DAJRC+y8hgCh7Nfm6jaALvqAJCwnjWe7aLS50e9Obh2bkvanGvlElSt493o08lacpxTpjMy5tonxj", - "0tI7jO55B7I/ZaFREydwz5RGl4tLzVbkImxh2w7+E95tuQHXfzSQT/pBfnFOVI6MQGjHvmqPxbDFhSZz", - "kfOw12z+gevZJATuA7Cvn8t6urHfspzHkYkOPiZZb1brAiGCDnv6IU80w6TO1bwLmuSgTPIxA4LZBwsh", - "tKlJINKUEgUZlVRDSGz+r1pmh4kqxrmSOMYtSVPQIJURQENnNdJlY9r1pQPBFQtBQmhSiDlLtEl44T5L", - "TIcToTqytcOvOcjVunRQBfk1pIqe5LRWxu9V2qNynmQfgzoCBuetJvkWw3nCyi2LUvtYVBVNz4Z/xJUy", - "GRT6+1K5m9D/0TVfNmMfV9gJ8mPySZlpxyP8+8T8fWpTXDCWOd5gFYapLTaBY9AALNzJbDUM8dou3YGE", - "nr5+qfc/wdwLZk2jgyLZKa0bxw+mCf5ouSsa7HVknZv3Ns1pgGpLR2Ut5FZLpyv+MeOTHRsOgFiRrJe2", - "HftmIlEltLXD1kLiRt1gEvO8urHSVIR2BtdRtyv5EXQuuemRMB4l4ObW9fQ96CvQb1ZGQhut/+Icy3mX", - "I0uz9svJ+/eQ5qkXSvOamCqblTd3aCJPMP+ybDnvKn1cVd9TzvyT6fg7IdMdYNQ87c/NWuHhUNVyIO+p", - "bVINYacR1dzRxg7eyqWU+5HrSBu3pX4vWENbFDj/VCvgbMqCqiEh1XRbSPHzLBE0vEjdyX8f6HDQd8zm", - "xIOdlpXwC8LrLAxNn5Em5AfQ1AmgS720HFkZuEXVQ3oHItCgj5SWQNO6gyu3M2Ocyq4T+MdD1trVWyKD", - "fekzodViTBHTzEagdYHSdncZXwDX7kB6S5RNaYZgc2VGIELbcndn/gxUV/C9KAk8UdhrBF3VDi0HHK3V", - "D8r21kY1DtXkXYjI+ga7XwbdBZPt+lRVIMq7HZ1t5auEBkWL1Axt9o/qIjfD7XWRw/TfPpQXHJ6xA9ez", - "6C5JS7HEQa26JDI8NxoWo0osOXVzp2usbptJcQ+E/AfzT6tuaRxoCkks9UJIRMsVcdZCLs6VjWgmvye3", - "+WRyGpDjyWQyJmd8pWPGI0JnYgHmJRGScMHdbJyaJO60TNvDKJBSyLZnsAl/gdMBIQ4Rb0XSSizsVnvS", - "KieTlyyPhqS89o5SI+ltlEMky2UQU1VsvJm4FjjoKY/20fRfydeoUvMf1PCYfDAHrq5NWFdv2WxV4y7P", - "b7Y4vPDqUe4czOnxSyr3EA7jORzbi9Vjm8FpC6lh0EQXlatN4c1cdAjQ3/FkZaxZcDANmhhIIqII0E+a", - "e8htlNnzQ3dB5hDBzl6Xft5Y173mLoj4pLoBYcUR1i9tN8Bd9uIPKqHn2E1/UlZC0Z0f5+6GlAOf+e8a", - "e35gRmH9fsnUhgN8u5oiSeXuu/OREVsAt/GaFBcE+6CoCkoXJrzvD8wnXeg/ZBZ0OJ33nSRWULsnSAar", - "tQ9FiYgYr1RJdfVf4lfniDafMcQWrwRDmEnv7MLdZXN5KXCnRgzSKK5ArkmgGw0SoJJouNc9BMubk7s0", - "YnbFVvsq40Ygter2QZ5i5FrwhsOfjt7dZ0yCOjqbaxuO6kuYQ17GyaePb8kyBk60+AycgJ3ldSYUGy6n", - "P468n45+xO+XLGUduA1okmDBKElsLikmiVhCWMQ959C6k5jOItdIZWPgL6Dkl8hY5wE1e7kUkbIQZby4", - "LbJSGtLNxiHszZE+6xC5LuN0dzja2bANoyLXJMilBK4b6QJRoJRFQh/bD4VQNpZMT0pRbCo/1DMYp7Bb", - "gVNxEf1J8PZW6gDkbE8czQXoLUVNd7AedQPnezCoebN67y7a7ydAV0TYE2SkeFw7NiYHlOzvI+7uVUo8", - "Ey6+B23tdbZaR8YuhHTeTXuScdq2/hDjrOPqsHb5Ry9jOq7NuXBU/5nsswUSR7CnjDBtYLkocGFvMPs0", - "Y/7i1EONuQlNwu8WINcNs1zbnyNc2d79Dr862Pw7g+rPitrnM2briNbyCrSp13fkwPGP7BdN5+0cFWpq", - "NRcKJSi3rBN77Wcrd4//DgAA///gocX++z0AAA==", + "7Fv/b+M2sv9X+NQH9BVwLCfZvr0aOKDZzbbIXbobNLt3PSRBQUtjiV2JVEnKjhvkfz8MScn6astOnLui", + "3R92tRLJGc585ivpBy8QaSY4cK286YMn4dcclH4jQgbmxRVo/CcQXAM3jzTLEhZQzQT3f1GC4zsVxJBS", + "fPpfCXNv6n3hr9f17Vfl41qPj6PaCvdpsusCjyMvBBVIluEK3hR5JGL2CwSa6JhqwgFCRbQgMyA0DCHE", + "Zx0DUVpI8B5H3icF8kxKutppb0xDqrbxiEsjCb3KwJt61FDpYPqSKU3EnOQKpOPeCMetg2TOwlCCMo+Z", + "FBlI7ZQSMG04h3uaZgmSuaKJIGeJFl5JWWnJeISsKE011Me/PeseKMHqez3y1elrcrnSWvCuGb+xrD78", + "m1enk+P2yLVA3FZHntM8p6mRk9srjjzL2I+gMsEVdOxdhObtXMiUam/qMa5PT9YUGdcQWRWkoBSNzOgW", + "4/bFw858fvFFCHOaJ1ZZb6mGSMhVm00W1uRyPKox/P+vOhm2NKriPBeR2kOaQcGXYTJXWqQg20zSNcAG", + "YbsAZBPePcoEZH0paZZB6E21zAHZaUpmgn8GiQdNpS2iOcRRvtpHSIVccOgHGXZJCIWQgK5CZSZEApR7", + "XVsZtI0M9EVj4jd/ef36ZNDkX3PKddP8X4+GmIOKWXbuPEE5PKQajjRLoc9x5EYOdd9lhEWu7deRBzxP", + "vemNlyU0gNAzDl6KhXkMIWELkBB6d6OK0iojdlWbMJrCcS42NTRWMclNWC5Nd289tqEYiihinZLMYqHF", + "J5nUba0+rLnRYk5VJg17axlXn8Yy0MR+I4xXYuFaeXRBWUJnCb7LgIeWIyUSo7m2/6TRcL/xkUbe0D08", + "jkwSwhAy0xsri6r87rbhI3NZBhLtccs7KHdXdGpqR5k0oEUeUsqSOmZ+ETH/1rwfByLtws6cSaXft8D2", + "NxF3huT9wJzQTho0BdWJZ6rUUsg6Ke/45PTV1z3w5zBwLHr56x4Yo1Qrfqcnuvb4v+7woWMwutrdEeUm", + "0zNWB0EumV5dI95daM3Yz5/BeCGGnMdAQ0OlCJHu+9oqMvZ3WLn4YIzzZ5rr2MA1EUuL3hTTU2ZT1VzH", + "QrLfTLKKXmLqxVpnaur7xQKnY7WkUQRyzIQvcIJfzEKbUoHIwGX9NJziLG9qnslK5JKYFxjAmYbiaypC", + "Nl+ZT+hIzDgaBCLnLjMvRIaETuwruNco+ORcBB0q/Y7xkIhck1RIIHSGj9eWbW/k5eXGpr6/3o3BOZ+L", + "In2nga6YF8pSA02/rU+o0/0YM0WYIpQoAwWCVcQ1io1cg1yAJDOqICTCussPGfCzqwtyOp4QlUHA5q5O", + "GBPyL5GTgHIyb2/llru9EKrJTWsfd//XevXVmFxYkjpmMiRMgzSEsFjA19aVCwkjsoQvF0DUkukgXlc5", + "ISgWITdSaWICLQ3i/7nlBZtcLEkMSUYwGKQmDpt5uL1lDDoGSZj+UpHZiqT0M+MRCWLKI1BrCnPGmWGK", + "aQXJnAhZfMP8fHzLP2IhtqSrEVkyHRPMMJBfw0CTKOMkAg6SJiNCeUjgPhMKiBIpFJvmsCRzoDqXYID3", + "4ez6dHzLb/k1DsoVzPOEJIx/VtNbfkRuPsZVhUrIhGJayJUVOBpJxHScz9DnFsI/ohkrnwsb+qpcTolc", + "Bpbhyv7nuPMqsZ0p+LNEzPyUKg3SVzLwU8q4L8HSU77IgNOMjVc0Tb7yRl7CAnCVkfMlZxkNYiAn40nT", + "YpbL5Ziar2MhI99NVf7lxdt376/fHZ2MJ+NYp4mJziBT9WGO4GcBdFmdb4b46LOYNs6zAPeV2ws5qhqK", + "N/IWIJW1t+PxZHz8Ggm5DXlT73Q8GaOvzqiOjWtA12WiplC67SrOwpBQAwW0gVpNb1a1doK5NQ7F7HBU", + "aWisDtvHOFoul0cYhY5ymQBHMwj/862RtxKohorUGtnfOtUy2Re+sIW3UcfJZPJf3/y5zoMAlEL7LyGA", + "KHs1+bqNoAu+oAkLCeNZ7totLnR705uHZuS9qca+USVK3j3ejTyVpynFOmMzLm2ifGPS0juM7nkHsj9l", + "oVETJ3DPlEaXi0vNVuQibGHbDv4T3m25Add/NJBP+kF+cU5UjoxAaMe+ao/FsMWFJnOR87DXbP6B69kk", + "BO4DsK+fy3q6sd+ynMeRiQ4+JllvVusCIYIOe/ohTzTDpM7VvAua5KBM8jEDgtkHCyG0qUkg0pQSBRmV", + "VENIbP6vWmaHiSrGuZI4xi1JU9AglRFAQ2c10mVj2vWlA8EVC0FCaFKIOUu0SXjhPktMhxOhOrK1w685", + "yNW6dFAF+TWkip7ktFbG71Xao3KeZB+DOgIG560m+RbDecLKLYtS+1hUFU3Phn/ElTIZFPr7Urmb0P/R", + "NV82Yx9X2AnyY/JJmWnHI/z7xPx9alNcMJY53mAVhqktNoFj0AAs3MlsNQzx2i7dgYSevn6p9z/B3Atm", + "TaODItkprRvHD6YJ/mi5KxrsdWSdm/c2zWmAaktHZS3kVkunK/4x45MdGw6AWJGsl7Yd+2YiUSW0tcPW", + "QuJG3WAS87y6sdJUhHYG11G3K/kRdC656ZEwHiXg5tb19D3oK9BvVkZCG63/4hzLeZcjS7P2y8n795Dm", + "qRdK85qYKpuVN3doIk8w/7JsOe8qfVxV31PO/JPp+Dsh0x1g1Dztz81a4eFQ1XIg76ltUg1hpxHV3NHG", + "Dt7KpZT7ketIG7elfi9YQ1sUOP9UK+BsyoKqISHVdFtI8fMsETS8SN3Jfx/ocNB3zObEg52WlfALwuss", + "DE2fkSbkB9DUCaBLvbQcWRm4RdVDegci0KCPlJZA07qDK7czY5zKrhP4x0PW2tVbIoN96TOh1WJMEdPM", + "RqB1gdJ2dxlfANfuQHpLlE1phmBzZUYgQttyd2f+DFRX8L0oCTxR2GsEXdUOLQccrdUPyvbWRjUO1eRd", + "iMj6BrtfBt0Fk+36VFUgyrsdnW3lq4QGRYvUDG32j+oiN8PtdZHD9N8+lBccnrED17PoLklLscRBrbok", + "Mjw3GhajSiw5dXOna6xum0lxD4T8B/NPq25pHGgKSSz1QkhEyxVx1kIuzpWNaCa/J7f5ZHIakOPJZDIm", + "Z3ylY8YjQmdiAeYlEZJwwd1snJok7rRM28MokFLItmewCX+B0wEhDhFvRdJKLOxWe9IqJ5OXLI+GpLz2", + "jlIj6W2UQyTLZRBTVWy8mbgWOOgpj/bR9F/J16hS8x/U8Jh8MAeurk1YV2/ZbFXjLs9vtji88OpR7hzM", + "6fFLKvcQDuM5HNuL1WObwWkLqWHQRBeVq03hzVx0CNDf8WRlrFlwMA2aGEgiogjQT5p7yG2U2fNDd0Hm", + "EMHOXpd+3ljXveYuiPikugFhxRHWL203wF324g8qoefYTX9SVkLRnR/n7oaUA5/57xp7fmBGYf1+ydSG", + "A3y7miJJ5e6785ERWwC38ZoUFwT7oKgKShcmvO8PzCdd6D9kFnQ4nfedJFZQuydIBqu1D0WJiBivVEl1", + "9V/iV+eINp8xxBavBEOYSe/swt1lc3kpcKdGDNIorkCuSaAbDRKgkmi41z0Ey5uTuzRidsVW+yrjRiC1", + "6vZBnmLkWvCGw5+O3t1nTII6OptrG47qS5hDXsbJp49vyTIGTrT4DJyAneV1JhQbLqc/jryfjn7E75cs", + "ZR24DWiSYMEoSWwuKSaJWEJYxD3n0LqTmM4i10hlY+AvoOSXyFjnATV7uRSRshBlvLgtslIa0s3GIezN", + "kT7rELku43R3ONrZsA2jItckyKUErhvpAlGglEVCH9sPhVA2lkxPSlFsKj/UMxinsFuBU3ER/Unw9lbq", + "AORsTxzNBegtRU13sB51A+d7MKh5s3rvLtrvJ0BXRNgTZKR4XDs2JgeU7O8j7u5VSjwTLr4Hbe11tlpH", + "xi6EdN5Ne5Jx2rb+EOOs4+qwdvlHL2M6rs25cFT/meyzBRJHsKeMMG1guShwYW8w+zRj/uLUQ425CU3C", + "7xYg1w2zXNufI1zZ3v0OvzrY/DuD6s+K2uczZuuI1vIKtKnXd+TA8Y/sF03n7RwVamo1FwolKLesE3vt", + "Zyt3j/8OAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -331,7 +333,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -355,12 +357,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -386,3 +388,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1087/deps/deps.gen.go b/internal/test/issues/issue-1087/deps/deps.gen.go index 8066ab2b57..55a8d8e2f1 100644 --- a/internal/test/issues/issue-1087/deps/deps.gen.go +++ b/internal/test/issues/issue-1087/deps/deps.gen.go @@ -5,7 +5,7 @@ package deps import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -45,41 +45,42 @@ type N410 = Error // DefaultError defines model for DefaultError. type DefaultError = Error -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/7SV34/jNBDH/5WR4TFq0+siobwVDtAiAacDnk6rlRtPmjmcsc+edLes+r8jO2nTH6tb", - "7qR9ahPPeL7zmR95UrXrvGNkiap6UgGjdxwxP9yUi/RTOxZkSX+195ZqLeR4/jE6Tu/wUXfe4mBpUFU3", - "5aJQxnWaWFVq1UurCtVhjHqDqlK3vNWWDOheWmQZr1OFCqjzlQeL+9W5xb5QsW6x0ynUtwEbValv5pP+", - "+XAa5z+F4ILa7wsl+Chzb7OSpxPvo2b164MARcBHTwGNKpTsfHofJRBv1D7dYjDWgXwWUam/OSl3gf5F", - "M4NbNkkfRpBWC/jgtmTQQB3QJO3axnQ/O4GcVMriplx+Hdfl57iu6hpjhLfIlBM54hwO7seDV6F4GftF", - "iD+7sCZjkK8IBvzUYxSoNSdoa4QJd4a3KL8K3qI8gXcG7hfHeMorP78KpjHSi3TeY+2CAXZgHW8wgN5q", - "snpts6632OjeyhD4ZRRflsaVljEaYDKAw36AxgXQvBteRyAGaRFW724zivHWFPQHHfEo1QfnMQgN+2Wo", - "zNNFwL9ahJ4NBrsj3kAr4iGKlj5CdigmoN+VZaEaFzotqlLEsnwz4SUW3GBIxA51fy7UcAYPLQbMOQyJ", - "UgQXaEOsJalogutARzDYEKOB9S7bRgxbqs80qesCnzTbpYIVREp+MFokkMgbS7GFwXKdwk+6NJs0Gmku", - "Akofkhhx2aB2HPsOw5ma1QZPRsmmKZVWMyy+f16naKMld4s2hpJKbd+dVe3K6SIj3sHkCgZFk41J4zpL", - "3OIOzYBSMHTP0JzBbQM+YESWAh7I2jFV6LQH18A/uEvLtEfwmkI8zffYYrvfdZdknj6moqb1kjf9/pi+", - "W3/EWnLfHk+rD2pstrF3phreXTkW6tjg2to/GlV9+PywTTOxvysuhuKwhq47ZTjJQwDRY00N1Yfaj+hO", - "26OPQ2tQ/g41A2J81HX64MUeZ/Bn63prsi3Tpx7hgaQlBg3HpKdGep+j3/84ULlcYf8P3XHJXjNMVxA3", - "LncYSQ75mzNoU3m3GOJA4c2snJWJuPPI2pOq1HJWzpaqUF5Lmwim9YMhueQ69MGqSs3V/m7/XwAAAP//", - "TAbhS+0IAAA=", + "tJXfj+M0EMf/lZHhMWrT6yKhvBUO0CIBpwOeTquVG0+aOZyxz550t6z6vyM7adMfq1vupH1qE894vvOZ", + "H3lSteu8Y2SJqnpSAaN3HDE/3JSL9FM7FmRJf7X3lmot5Hj+MTpO7/BRd97iYGlQVTflolDGdZpYVWrV", + "S6sK1WGMeoOqUre81ZYM6F5aZBmvU4UKqPOVB4v71bnFvlCxbrHTKdS3ARtVqW/mk/75cBrnP4Xggtrv", + "CyX4KHNvs5KnE++jZvXrgwBFwEdPAY0qlOx8eh8lEG/UPt1iMNaBfBZRqb85KXeB/kUzg1s2SR9GkFYL", + "+OC2ZNBAHdAk7drGdD87gZxUyuKmXH4d1+XnuK7qGmOEt8iUEzniHA7ux4NXoXgZ+0WIP7uwJmOQrwgG", + "/NRjFKg1J2hrhAl3hrcovwreojyBdwbuF8d4yis/vwqmMdKLdN5j7YIBdmAdbzCA3mqyem2zrrfY6N7K", + "EPhlFF+WxpWWMRpgMoDDfoDGBdC8G15HIAZpEVbvbjOK8dYU9Acd8SjVB+cxCA37ZajM00XAv1qEng0G", + "uyPeQCviIYqWPkJ2KCag35VloRoXOi2qUsSyfDPhJRbcYEjEDnV/LtRwBg8tBsw5DIlSBBdoQ6wlqWiC", + "60BHMNgQo4H1LttGDFuqzzSp6wKfNNulghVESn4wWiSQyBtLsYXBcp3CT7o0mzQaaS4CSh+SGHHZoHYc", + "+w7DmZrVBk9GyaYplVYzLL5/XqdooyV3izaGkkpt351V7crpIiPeweQKBkWTjUnjOkvc4g7NgFIwdM/Q", + "nMFtAz5gRJYCHsjaMVXotAfXwD+4S8u0R/CaQjzN99hiu991l2SePqaipvWSN/3+mL5bf8Ract8eT6sP", + "amy2sXemGt5dORbq2ODa2j8aVX34/LBNM7G/Ky6G4rCGrjtlOMlDANFjTQ3Vh9qP6E7bo49Da1D+DjUD", + "YnzUdfrgxR5n8GfremuyLdOnHuGBpCUGDcekp0Z6n6Pf/zhQuVxh/w/dccleM0xXEDcudxhJDvmbM2hT", + "ebcY4kDhzayclYm488jak6rUclbOlqpQXkubCKb1gyG55Dr0wapKzdX+bv9fAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -87,7 +88,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -105,12 +106,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -136,3 +137,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1093/api/child/child.gen.go b/internal/test/issues/issue-1093/api/child/child.gen.go index d50664c315..1275e1b202 100644 --- a/internal/test/issues/issue-1093/api/child/child.gen.go +++ b/internal/test/issues/issue-1093/api/child/child.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -188,32 +188,34 @@ func (sh *strictHandler) GetPets(ctx *gin.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/2xRwW7bMAz9FYHb0Yi97aYfGHYLht7SoFBlOlZgSyxJFwgC/3tBuUEaoCeR9uPj43tX", - "iGWmkjGrgL+CxBHnUEsKjFlf9qi140LImrD+y2FGe/VCCB5EOeUTrA1oOH3zfW2A8W1JjD34wzZ9bG6o", - "8nrGqLAaLOWhGEGPEjmRppLBw9OYxMUxTb0TwujSTIVV3Fx6nMQNXGanI7pNcsVAA5p0Mv46CA28I8vG", - "92vXmdhCmAMl8PBn1+06aICCjvXAlnAz5LSd/6jnP+rCWRyh3pfLRRStDFr7RZDdGMSFGFHEaXnOUJdy", - "MJ5/PXj4i7q3TWaQUMmy+fu76+yJJSvmKiAQTSnWwfYspuIWllU/GQfw8KO9p9l+Rtl+ybFa/HhKcLJU", - "fcMyuZsGAxpUkM008IcrLDyBh3Yzcz2uHwEAAP//SKTQrDoCAAA=", + "bFHBbtswDP0VgdvRiL3tph8YdguG3tKgUGU6VmBLLEkXCAL/e0G5QRqgJ5H24+Pje1eIZaaSMauAv4LE", + "EedQSwqMWV/2qLXjQsiasP7LYUZ79UIIHkQ55ROsDWg4ffN9bYDxbUmMPfjDNn1sbqjyesaosBos5aEY", + "QY8SOZGmksHD05jExTFNvRPC6NJMhVXcXHqcxA1cZqcjuk1yxUADmnQy/joIDbwjy8b3a9eZ2EKYAyXw", + "8GfX7TpogIKO9cCWcDPktJ3/qOc/6sJZHKHel8tFFK0MWvtFkN0YxIUYUcRpec5Ql3Iwnn89ePiLurdN", + "ZpBQybL5+7vr7IklK+YqIBBNKdbB9iym4haWVT8ZB/Dwo72n2X5G2X7JsVr8eEpwslR9wzK5mwYDGlSQ", + "zTTwhyssPIGHdjNzPa4fAQAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -221,7 +223,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -245,12 +247,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -276,3 +278,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1093/api/parent/parent.gen.go b/internal/test/issues/issue-1093/api/parent/parent.gen.go index 6f6f7d869b..d1696c0068 100644 --- a/internal/test/issues/issue-1093/api/parent/parent.gen.go +++ b/internal/test/issues/issue-1093/api/parent/parent.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -193,32 +193,34 @@ func (sh *strictHandler) GetPets(ctx *gin.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/2xRwa7TMBD8FWvhGDUBbv4BxO0JcXv04Dqb2lViL7sbUBXl39E6rVAlTru2xjPjmQ1i", - "XagWLCrgN5CYcAltfUO1QVwJWTO2yxIWtKl3QvAgyrlcYe9Aw/U/93sHjL/WzDiCfz9en7snql5uGBV2", - "g+UyVSMYUSJn0lwLePiRsjgKjEWdEEaXgriljjiL+5NyTC4wurxQZcXRXe5OE7qY8jw2PHSgWWcTO1ig", - "g9/IcrB/Og1mvRKWQBk8fDkNpwE6oKCpfbcnPHK5HmG8uvuOunIRR6hu4ro0cbmLoq1B23kV5GY7xIgi", - "TuvPAk2Ug/F8G8HDV9Q3U7K4hGqRI+3Pw2Aj1qLm3W8QiOYc28P+Jubi2ZltHxkn8PCh/1dq/2i0tzpb", - "0q9/CE7WZmxaZ/cUN6BBBdnSAv++wcozeOgfMe7n/W8AAAD///mNvoM7AgAA", + "bFHBrtMwEPwVa+EYNQFu/gHE7Qlxe/TgOpvaVWIvuxtQFeXf0TqtUCVOu7bGM+OZDWJdqBYsKuA3kJhw", + "CW19Q7VBXAlZM7bLEha0qXdC8CDKuVxh70DD9T/3eweMv9bMOIJ/P16fuyeqXm4YFXaD5TJVIxhRImfS", + "XAt4+JGyOAqMRZ0QRpeCuKWOOIv7k3JMLjC6vFBlxdFd7k4TupjyPDY8dKBZZxM7WKCD38hysH86DWa9", + "EpZAGTx8OQ2nATqgoKl9tyc8crkeYby6+466chFHqG7iujRxuYuirUHbeRXkZjvEiCJO688CTZSD8Xwb", + "wcNX1DdTsriEapEj7c/DYCPWoubdbxCI5hzbw/4m5uLZmW0fGSfw8KH/V2r/aLS3OlvSr38ITtZmbFpn", + "9xQ3oEEF2dIC/77ByjN46B8x7uf9bwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -226,7 +228,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -244,12 +246,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -275,3 +277,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1180/issue.gen.go b/internal/test/issues/issue-1180/issue.gen.go index ffab4accf7..4f11b798d5 100644 --- a/internal/test/issues/issue-1180/issue.gen.go +++ b/internal/test/issues/issue-1180/issue.gen.go @@ -5,7 +5,7 @@ package issue1180 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -323,32 +323,34 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/7RRPY/TQBD9K9aDcuX13XXbUaErkBC5DlEs9iQZ5P1gdhJxsvzf0a4TIBHtVfbMzrz3", - "5r0FYwo5RYpa4BYIlZxioVbsOOSZvlxatTOmqBS1/ir9Uptnz7FWZTxS8K3/mgkORYXjAeu6GkxURuGs", - "nCIcPnSl4XZXri59/0GjbrMc96nCzDzShTT6UBE/Pb9gNVDWuZYvVLTbkZxJYHAmKRv8Qz/0Qx1MmaLP", - "DIenfugfYJC9HtthdlPwWTiw8pnskr34sNa3A7XzUibxVfHzBIePpLvblQYnPpCSFLivC6oRjQLmKrlN", - "wEDo54mFJjiVE5l/3NonCV7hwFGfHmHu7TMo+tru3SRj/WZuQ3ochvp5L7SHwzv7N0/7Z87eJdmcfkv5", - "HJUOJP/VX7lLy20jPskMh6NqdtZeQlMq2k9EOfjce65bvwMAAP//QUrtxqoCAAA=", + "tFE9j9NAEP0r1oNy5fXdddtRoSuQELkOUSz2JBnk/WB2EnGy/N/RrhMgEe1V9szOvPfmvQVjCjlFilrg", + "FgiVnGKhVuw45Jm+XFq1M6aoFLX+Kv1Sm2fPsVZlPFLwrf+aCQ5FheMB67oaTFRG4aycIhw+dKXhdleu", + "Ln3/QaNusxz3qcLMPNKFNPpQET89v2A1UNa5li9UtNuRnElgcCYpG/xDP/RDHUyZos8Mh6d+6B9gkL0e", + "22F2U/BZOLDymeySvfiw1rcDtfNSJvFV8fMEh4+ku9uVBic+kJIUuK8LqhGNAuYquU3AQOjniYUmOJUT", + "mX/c2icJXuHAUZ8eYe7tMyj62u7dJGP9Zm5DehyG+nkvtIfDO/s3T/tnzt4l2Zx+S/kclQ4k/9VfuUvL", + "bSM+yQyHo2p21l5CUyraT0Q5+Nx7rlu/AwAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -356,7 +358,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -374,12 +376,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -405,3 +407,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go index 13cce371bf..e548f06834 100644 --- a/internal/test/issues/issue-1182/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1182/pkg1/pkg1.gen.go @@ -5,7 +5,7 @@ package pkg1 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -365,31 +365,33 @@ func (sh *strictHandler) TestGet(ctx echo.Context) error { return nil } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/3yQMU/DMBCF/4r1YIyStGzemFAHllKJASFknJfGtLEt+1qEqvx35LQUsTCdz3fv7r53", - "gg1jDJ5eMvQJiTkGnzkncbddvq0vP89OhjV7JnrLUu2YbXJRXPDQuFc/UhXeP2hFfQ7ODspllYoqsVMS", - "VJ/CqIwPMjCpaOzObIlpmio434cydu8sfZ43eDMSGo+rDaYK4mRf0g2zqCemIxMqHJny+YJF3dZtaQyR", - "3kQHjbu6rReoEI0MM1EjzFIeW84hRCZTCFbdZfIDBdVfG5ZtW8JtYg+Nm+bXseba1/zjVaHLh3E06Qu6", - "bFbliqtfZ/w8A2XolxMOaQ+NQSTqprnQFEndkXE0sTYO0+v0HQAA//9bF49xvAEAAA==", + "fJAxT8MwEIX/ivVgjJK0bN6YUAeWUokBIWScl8a0sS37WoSq/HfktBSxMJ3Pd+/uvneCDWMMnl4y9AmJ", + "OQafOSdxt12+rS8/z06GNXsmestS7ZhtclFc8NC4Vz9SFd4/aEV9Ds4OymWViiqxUxJUn8KojA8yMKlo", + "7M5siWmaKjjfhzJ27yx9njd4MxIaj6sNpgriZF/SDbOoJ6YjEyocmfL5gkXd1m1pDJHeRAeNu7qtF6gQ", + "jQwzUSPMUh5bziFEJlMIVt1l8gMF1V8blm1bwm1iD42b5tex5trX/ONVocuHcTTpC7psVuWKq19n/DwD", + "ZeiXEw5pD41BJOqmudAUSd2RcTSxNg7T6/QdAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -397,7 +399,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -421,12 +423,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -452,3 +454,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go index 906298efc5..21ba74e586 100644 --- a/internal/test/issues/issue-1182/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1182/pkg2/pkg2.gen.go @@ -5,7 +5,7 @@ package pkg2 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -211,30 +211,32 @@ type strictHandler struct { middlewares []StrictMiddlewareFunc } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/zSOMU/DMBSE/4p1c+S2YvPGyMBSKjEgBuNcsCGxLb/XMkT+7yihjJ/e++5uRShLLZlZ", - "BW5Fo9SShTuc7/CaNJ45sTEHboeRElqqmkqGw6P5t0z5+GJQ8xNTiCaJaZvVOBotZmplMT4XjWym+vDt", - "P4ne+4CUp7LFzikwy96Q/UI4PD9d0Ado0nnDC0XNC9uNDQNubPK34GSP9rg9lsrsa4LDgz3aEwZUr1Hg", - "8nWeB8iuCtzbimub4RBVqzsc7p5S1I5kXXy1PqG/998AAAD//4Nm84whAQAA", + "NI4xT8MwFIT/inVz5LZi88bIwFIqMSAG41ywIbEtv9cyRP7vKKGMn9777m5FKEstmVkFbkWj1JKFO5zv", + "8Jo0njmxMQduh5ESWqqaSobDo/m3TPn4YlDzE1OIJolpm9U4Gi1mamUxPheNbKb68O0/id77gJSnssXO", + "KTDL3pD9Qjg8P13QB2jSecMLRc0L240NA25s8rfgZI/2uD2WyuxrgsODPdoTBlSvUeDydZ4HyK4K3NuK", + "a5vhEFWrOxzunlLUjmRdfLU+ob/33wAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -242,7 +244,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -260,12 +262,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -291,3 +293,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1189/issue1189.gen.go b/internal/test/issues/issue-1189/issue1189.gen.go index c13992c9b5..45bd54e759 100644 --- a/internal/test/issues/issue-1189/issue1189.gen.go +++ b/internal/test/issues/issue-1189/issue1189.gen.go @@ -5,7 +5,7 @@ package param import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -531,30 +531,32 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6yRsU4zMRCE32X+v7RyJ+jcARUVDV2UwlzWiZFvd2Vviuh0747sI4pEC9vMyPZ+lmYW", - "TDKrMLFV+AV1OtMcujWq1lSLKBVL1E9jonx8ai7w9S3C7xfYVQke1UriE1a3gPgyw+8RReDwEQoO7uez", - "w+o22nOn5fw3tJdGE6Zf0to4JI4Cz5ecHUSJgyZ4PO7G3QgHDXbuoQy3rE7UpQUWLAm/HuHx3i4dClUV", - "rluMD+PYZBI24r4TVHOa+tbwWYXvbTT3v1CEx7/hXtfw3dX2+XqbrwAAAP//gr+fh9IBAAA=", + "rJGxTjMxEITfZf6/tHIn6NwBFRUNXZTCXNaJkW93ZW+K6HTvjuwjikQL28zI9n6WZhZMMqswsVX4BXU6", + "0xy6NarWVIsoFUvUT2OifHxqLvD1LcLvF9hVCR7VSuITVreA+DLD7xFF4PARCg7u57PD6jbac6fl/De0", + "l0YTpl/S2jgkjgLPl5wdRImDJng87sbdCAcNdu6hDLesTtSlBRYsCb8e4fHeLh0KVRWuW4wP49hkEjbi", + "vhNUc5r61vBZhe9tNPe/UITHv+Fe1/Dd1fb5epuvAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -562,7 +564,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -580,12 +582,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -611,3 +613,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go index 72270f9356..cb42ffded3 100644 --- a/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go +++ b/internal/test/issues/issue-1208-1209/issue-multi-json.gen.go @@ -5,7 +5,7 @@ package multijson import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -505,30 +505,32 @@ func (sh *strictHandler) Test(ctx *gin.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/8ySQU4DMQxF7/JhR9Skwy43YM8F0qnTBk1tKwkLqObuyGkFqlQW7JiNPXHeT/5Xzpjl", - "pMLEvSGeUampcKPxs0ufVmbhTtytTapLmVMvwn6X6tNbE7b1Nh/plKx7rJQR8eB/dP1l2ozAuroblSzy", - "R5UsgtU+dwWud61WtIpS7eViIBda9pN1/UMJEa3XwgcM2HTuE9u7hDGFsyDy+7I4iBInLYh43oRNgIOm", - "fhwqvlMbeR1oFDth2H3ZI+LVhu426imEfxy1wxS2v23+9uHtvYyg1q8AAAD//25zbQ5XAgAA", + "zJJBTgMxDEXv8mFH1KTDLjdgzwXSqdMGTW0rCQuo5u7IaQWqVBbsmI09cd5P/lfOmOWkwsS9IZ5Rqalw", + "o/GzS59WZuFO3K1NqkuZUy/Cfpfq01sTtvU2H+mUrHuslBHx4H90/WXajMC6uhuVLPJHlSyC1T53Ba53", + "rVa0ilLt5WIgF1r2k3X9QwkRrdfCBwzYdO4T27uEMYWzIPL7sjiIEictiHjehE2Ag6Z+HCq+Uxt5HWgU", + "O2HYfdkj4tWG7jbqKYR/HLXDFLa/bf724e29jKDWrwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -536,7 +538,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -554,12 +556,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -585,3 +587,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go index 2b4d87954a..34e300a96c 100644 --- a/internal/test/issues/issue-1212/pkg1/pkg1.gen.go +++ b/internal/test/issues/issue-1212/pkg1/pkg1.gen.go @@ -5,7 +5,7 @@ package pkg1 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -405,30 +405,32 @@ func (sh *strictHandler) Test(ctx *gin.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4yRMU/DMBCF/8uDMapD2DwyILGzIze5pAbnzrKvA6r635FtaFSpSM2SO9vfe6d3J4yy", - "RmFizbAnJMpROFNt4tcyfChlLc0orMS1XI9BfXRJTaLglKZymMcDra5iSSIl9U3kMwu/uFTKx0QzLB7M", - "5mkalk312ruEc1eRV5G7kFkE5/Z1vzNss++b7/VAs6cwDaXS70iwyJo8L6gKF83b2NNNrICeZ4HlYwgd", - "JBK76GHxvOt3PTpEp4eqYv7iXKj+ioNTL/w2weK9XHbXSxj6/r8gLu/MtqkWxU8AAAD//+WESHLXAQAA", + "jJExT8MwEIX/y4MxqkPYPDIgsbMjN7mkBufOsq8DqvrfkW1oVKlIzZI72997p3cnjLJGYWLNsCckylE4", + "U23i1zJ8KGUtzSisxLVcj0F9dElNouCUpnKYxwOtrmJJIiX1TeQzC7+4VMrHRDMsHszmaRqWTfXau4Rz", + "V5FXkbuQWQTn9nW/M2yz75vv9UCzpzANpdLvSLDImjwvqAoXzdvY002sgJ5ngeVjCB0kErvoYfG863c9", + "OkSnh6pi/uJcqP6Kg1Mv/DbB4r1cdtdLGPr+vyAu78y2qRbFTwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -436,7 +438,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -460,12 +462,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -491,3 +493,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go index 1aeee27bac..778ed9cbfd 100644 --- a/internal/test/issues/issue-1212/pkg2/pkg2.gen.go +++ b/internal/test/issues/issue-1212/pkg2/pkg2.gen.go @@ -5,7 +5,7 @@ package pkg2 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -242,30 +242,31 @@ type strictHandler struct { options StrictGinServerOptions } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4SPwU4EIQyG36V6JIurN44efA92trgYpm3a7sFM5t0NYGJMJlku/MD/5aMbLLwKE5Ib", - "pA0UTZgMx8HRvO8LkyONuN6bV8nqUbFlx2u/tOWGa+5JlAXV6+S/jOk9a4/PigUSPMU/XZyYxUtW2MNo", - "fzA/ahdm2OcKv+Yhu0zR/x+Uiu36Omb5FoQE5lrpEwZcpuyAOB8SnalUGBLdWwvAgpSlQoK308vpDAEk", - "+83m8/4TAAD//08ZxXtaAQAA", + "hI/BTgQhDIbfpXoki6s3jh58D3a2uBimbdruwUzm3Q1gYkwmWS78wP/loxssvAoTkhukDRRNmAzHwdG8", + "7wuTI4243ptXyepRsWXHa7+05YZr7kmUBdXr5L+M6T1rj8+KBRI8xT9dnJjFS1bYw2h/MD9qF2bY5wq/", + "5iG7TNH/H5SK7fo6ZvkWhATmWukTBlym7IA4HxKdqVQYEt1bC8CClKVCgrfTy+kMAST7zebz/hMAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -273,7 +274,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -291,12 +292,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -322,3 +323,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go index c9c57df5fb..f1f561ce10 100644 --- a/internal/test/issues/issue-1378/bionicle/bionicle.gen.go +++ b/internal/test/issues/issue-1378/bionicle/bionicle.gen.go @@ -5,7 +5,7 @@ package bionicle import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -328,32 +328,34 @@ func (sh *strictHandler) GetBionicleName(w http.ResponseWriter, r *http.Request, } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5SRMU8zMQyG/0rl7xujyxWYbuyCWGBhqzqkqa+XqpcEx0VCp/x35FyPXikMZLEcO3n8", - "+h3Ahj4Gj54TNANEQ6ZHRirZ1gXv7BGfTY+S7zBZcpFd8NCA3C5Cu+AOF7YzZCwjgQInxWi4AwW+vByD", - "AsK3kyPcQcN0QgXJdtgb+Zk/ovQlJuf3kHOeimWO1XmOMiGFiMQOS8WfJ/v+fs5aj10bNXWF7QEtjxTn", - "23Ar7RUTgwJ2LNApfUdKY31Z1VUNWUGI6E100MB9VVdLUEV4GU1P29OD8LPc7ZEliAIjqKcdNPCIvJov", - "Wl25sB7gP2ELDfzTF6/0pUVfuZQ3Ij3F4NO4obu6lmCDZ/SFbmI8Olv4+pBEzzBz4ifY2Qr95UMuu3v4", - "49fB40v7q6JbyCZP5zMAAP//9Jg3p6cCAAA=", + "lJExTzMxDIb/SuXvG6PLFZhu7IJYYGGrOqSpr5eqlwTHRUKn/HfkXI9eKQxksRw7efz6HcCGPgaPnhM0", + "A0RDpkdGKtnWBe/sEZ9Nj5LvMFlykV3w0IDcLkK74A4XtjNkLCOBAifFaLgDBb68HIMCwreTI9xBw3RC", + "Bcl22Bv5mT+i9CUm5/eQc56KZY7VeY4yIYWIxA5LxZ8n+/5+zlqPXRs1dYXtAS2PFOfbcCvtFRODAnYs", + "0Cl9R0pjfVnVVQ1ZQYjoTXTQwH1VV0tQRXgZTU/b04Pws9ztkSWIAiOopx008Ii8mi9aXbmwHuA/YQsN", + "/NMXr/SlRV+5lDciPcXg07ihu7qWYINn9IVuYjw6W/j6kETPMHPiJ9jZCv3lQy67e/jj18HjS/urolvI", + "Jk/nMwAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -361,7 +363,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -385,12 +387,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -416,3 +418,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1378/common/common.gen.go b/internal/test/issues/issue-1378/common/common.gen.go index 0e725531e7..91da73aeb9 100644 --- a/internal/test/issues/issue-1378/common/common.gen.go +++ b/internal/test/issues/issue-1378/common/common.gen.go @@ -5,7 +5,7 @@ package common import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -180,30 +180,31 @@ type strictHandler struct { options StrictHTTPServerOptions } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/0TMP08DMQwF8O/y5uh0FVt2BhYWuiGGkJjW6Gobx0VCVb47Sk+IyX/eT++GqhdTIYmO", - "fEOvZ7qU+/rofvRSWU5P7VnjhSTm21yNPJjuqGqjOePHCBk9nOWEMRKcvq7s1JBfd/WW/pS+f1INjMlY", - "PnQWNOrV2YJVkHGkHkgIjo3+z2/yvueHZV1WjAQ1kmKMjIdlXQ5IsBLnjizXbRu/AQAA//9/cprb3gAA", - "AA==", + "RMw/TwMxDAXw7/Lm6HQVW3YGFha6IYaQmNboahvHRUJVvjtKT4jJf95P74aqF1MhiY58Q69nupT7+uh+", + "9FJZTk/tWeOFJObbXI08mO6oaqM548cIGT2c5YQxEpy+ruzUkF939Zb+lL5/Ug2MyVg+dBY06tXZglWQ", + "caQeSAiOjf7Pb/K+54dlXVaMBDWSYoyMh2VdDkiwEueOLNdtG78BAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -211,7 +212,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -229,12 +230,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -260,3 +261,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go index b11772fd3c..8b38f2010a 100644 --- a/internal/test/issues/issue-1378/fooservice/fooservice.gen.go +++ b/internal/test/issues/issue-1378/fooservice/fooservice.gen.go @@ -5,7 +5,7 @@ package fooservice import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -288,32 +288,34 @@ func (sh *strictHandler) GetBionicleName(w http.ResponseWriter, r *http.Request, } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5RRQU/zMAz9K5O/7xg1HXDqcRfEBS7cpgllmbtmWpPgeEioyn9HTldtYwOJXpzEr37P", - "7w1gQx+DR88JmgGiIdMjI5Xb2gXv7B7fpsOz6VEaG0yWXGQXPDQgr7PQzrjDme0MGctIoMBJMxruQIEv", - "f45FAeH7wRFuoGE6oIJkO+yNTObPKLjE5PwWcs5T81LQ4ngomilEJHZYIP4o8fugc9LliFqpCRXWO7Q8", - "0jnfhusdXzExKGDHQjpdP5DS2J9XdVVDVhAiehMdNHBf1dUcVHGgSNOTfD0If5a3LbIU2cAI1dMGGnhE", - "Xpw7ri5yWQ7wn7CFBv7pU3r6BNG3c8sr8SDF4NNo1V1dS7HBM/oiw8S4d7YI0bskiw1n2dxiPYajr5PJ", - "xc2HP3IEjy/tjzv+wrbK0/cVAAD//37MjEPUAgAA", + "lFFBT/MwDP0rk7/vGDUdcOpxF8QFLtymCWWZu2Zak+B4SKjKf0dOV21jA4lenMSvfs/vDWBDH4NHzwma", + "AaIh0yMjldvaBe/sHt+mw7PpURobTJZcZBc8NCCvs9DOuMOZ7QwZy0igwEkzGu5AgS9/jkUB4fvBEW6g", + "YTqggmQ77I1M5s8ouMTk/BZyzlPzUtDieCiaKUQkdlgg/ijx+6Bz0uWIWqkJFdY7tDzSOd+G6x1fMTEo", + "YMdCOl0/kNLYn1d1VUNWECJ6Ex00cF/V1RxUcaBI05N8PQh/lrctshTZwAjV0wYaeERenDuuLnJZDvCf", + "sIUG/ulTevoE0bdzyyvxIMXg02jVXV1LscEz+iLDxLh3tgjRuySLDWfZ3GI9hqOvk8nFzYc/cgSPL+2P", + "O/7CtsrT9xUAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -321,7 +323,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -351,12 +353,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -382,3 +384,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1397/issue1397.gen.go b/internal/test/issues/issue-1397/issue1397.gen.go index 8d51c9d305..c4330e0475 100644 --- a/internal/test/issues/issue-1397/issue1397.gen.go +++ b/internal/test/issues/issue-1397/issue1397.gen.go @@ -5,7 +5,7 @@ package issue1397 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -394,33 +394,34 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/8xTO2/bMBD+K8K1W2XLj3bh1g4FPLRD4C3IQEsnmQbFo8lTYsHQfw+OUmzkBSRbJh2O", - "9/F76HiGklpPDh1HUGeI5R5bncotRpavD+QxsMHUrQ3aailVhbEMxrMhBwp+ZzoE3WdUZ+i6NrvXtsMI", - "ORjGNiGlDeoWKEGWkE/VCu5y4N4jKIgcjGtgyKHVp82I/HU5TQxymESs3hLhMDJWGe0OWHL2YHifaWup", - "1NJ1ukXI3zU0seyILGr3nOeFviGHgMfOBKzE0nTHBXA1NAqBHE6zhmbSnCUVCv71EvANHjuM/D/J/ivo", - "C+/6Y/6o4y9hUQCfMw2DYIyrCZTrrJWFQKe9AQXr+WIubF7zPnkoeFrHBtNH/GmJZVOBGnd1FIyR/1DV", - "y0xJjtGlce29NWUCpJt+HKIk+rTwUn0PWIOCb8X1RRTTcyi2k9wUSvTk4pjsavHz9V9qiKo0PAyPAQAA", - "///99gukXwMAAA==", + "zFM7b9swEP4rwrVbZcuPduHWDgU8tEPgLchASyeZBsWjyVNiwdB/D45SbOQFJFsmHY738XvoeIaSWk8O", + "HUdQZ4jlHludyi1Glq8P5DGwwdStDdpqKVWFsQzGsyEHCn5nOgTdZ1Rn6Lo2u9e2wwg5GMY2IaUN6hYo", + "QZaQT9UK7nLg3iMoiByMa2DIodWnzYj8dTlNDHKYRKzeEuEwMlYZ7Q5YcvZgeJ9pa6nU0nW6RcjfNTSx", + "7Igsavec54W+IYeAx84ErMTSdMcFcDU0CoEcTrOGZtKcJRUK/vUS8A0eO4z8P8n+K+gL7/pj/qjjL2FR", + "AJ8zDYNgjKsJlOuslYVAp70BBev5Yi5sXvM+eSh4WscG00f8aYllU4Ead3UUjJH/UNXLTEmO0aVx7b01", + "ZQKkm34coiT6tPBSfQ9Yg4JvxfVFFNNzKLaT3BRK9OTimOxq8fP1X2qIqjQ8DI8BAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -428,7 +429,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -446,12 +447,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -477,3 +478,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go index 7e5a0c7929..e85c0b1bf2 100644 --- a/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-echo/issue1529.gen.go @@ -5,7 +5,7 @@ package issue1529 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -430,30 +430,32 @@ func (sh *strictHandler) Test(ctx echo.Context) error { return nil } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6zPMUsEMRAF4L8iT8twWbWL2FgI9pbXxDjr5cjNDMlYyLL/XRIXFizFad4072NmQZKL", - "ChNbQ1jQ0okucayv1KynfSkhQN7OlAzrujpkngWBP0txECWOmhFwf5gOt3DQaKcheNuIDxohSjVaFn55", - "R/jxHSo1FW40GnfT1CMJG/HoRNWS02j5cxPej+zbTaUZAdd+/8JvL/jh92t/Ew9XWmXOhR6PeIr1iH82", - "n0X+YG7zHQAA//9fnz6pkQEAAA==", + "rM8xSwQxEAXgvyJPy3BZtYvYWAj2ltfEOOvlyM0MyVjIsv9dEhcWLMVp3jTvY2ZBkosKE1tDWNDSiS5x", + "rK/UrKd9KSFA3s6UDOu6OmSeBYE/S3EQJY6aEXB/mA63cNBopyF424gPGiFKNVoWfnlH+PEdKjUVbjQa", + "d9PUIwkb8ehE1ZLTaPlzE96P7NtNpRkB137/wm8v+OH3a38TD1daZc6FHo94ivWIfzafRf5gbvMdAAD/", + "/w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -461,7 +463,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -479,12 +481,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -510,3 +512,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go index 4ead2d3d10..5a9b77e70a 100644 --- a/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-fiber/issue1529.gen.go @@ -5,7 +5,7 @@ package issue1529 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -406,30 +406,32 @@ func (sh *strictHandler) Test(ctx *fiber.Ctx) error { return nil } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6zPMUsEMRAF4L8iT8twWbWL2FgI9pbXxDjr5cjNDMlYyLL/XRIXFizFad4072NmQZKL", - "ChNbQ1jQ0okucayv1KynfSkhQN7OlAzrujpkngWBP0txECWOmhFwf5gOt3DQaKcheNuIDxohSjVaFn55", - "R/jxHSo1FW40GnfT1CMJG/HoRNWS02j5cxPej+zbTaUZAdd+/8JvL/jh92t/Ew9XWmXOhR6PeIr1iH82", - "n0X+YG7zHQAA//9fnz6pkQEAAA==", + "rM8xSwQxEAXgvyJPy3BZtYvYWAj2ltfEOOvlyM0MyVjIsv9dEhcWLMVp3jTvY2ZBkosKE1tDWNDSiS5x", + "rK/UrKd9KSFA3s6UDOu6OmSeBYE/S3EQJY6aEXB/mA63cNBopyF424gPGiFKNVoWfnlH+PEdKjUVbjQa", + "d9PUIwkb8ehE1ZLTaPlzE96P7NtNpRkB137/wm8v+OH3a38TD1daZc6FHo94ivWIfzafRf5gbvMdAAD/", + "/w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -437,7 +439,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -455,12 +457,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -486,3 +488,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go index 0a990102f2..e630e0fe63 100644 --- a/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go +++ b/internal/test/issues/issue-1529/strict-iris/issue1529.gen.go @@ -5,7 +5,7 @@ package issue1529 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -391,30 +391,32 @@ func (sh *strictHandler) Test(ctx iris.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6zPMUsEMRAF4L8iT8twWbWL2FgI9pbXxDjr5cjNDMlYyLL/XRIXFizFad4072NmQZKL", - "ChNbQ1jQ0okucayv1KynfSkhQN7OlAzrujpkngWBP0txECWOmhFwf5gOt3DQaKcheNuIDxohSjVaFn55", - "R/jxHSo1FW40GnfT1CMJG/HoRNWS02j5cxPej+zbTaUZAdd+/8JvL/jh92t/Ew9XWmXOhR6PeIr1iH82", - "n0X+YG7zHQAA//9fnz6pkQEAAA==", + "rM8xSwQxEAXgvyJPy3BZtYvYWAj2ltfEOOvlyM0MyVjIsv9dEhcWLMVp3jTvY2ZBkosKE1tDWNDSiS5x", + "rK/UrKd9KSFA3s6UDOu6OmSeBYE/S3EQJY6aEXB/mA63cNBopyF424gPGiFKNVoWfnlH+PEdKjUVbjQa", + "d9PUIwkb8ehE1ZLTaPlzE96P7NtNpRkB137/wm8v+OH3a38TD1daZc6FHo94ivWIfzafRf5gbvMdAAD/", + "/w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -422,7 +424,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -440,12 +442,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -471,3 +473,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-312/issue.gen.go b/internal/test/issues/issue-312/issue.gen.go index e149b26d44..71fa081088 100644 --- a/internal/test/issues/issue-312/issue.gen.go +++ b/internal/test/issues/issue-312/issue.gen.go @@ -5,7 +5,7 @@ package issue312 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -527,35 +527,37 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/6xUPW/bMBD9K8S1o2A58aaxRVF4KTIUXQIPrHSSmZof5Z2MGgb/e3Gk7NqxjAzNFIX3", - "eO/de0cfofU2eIeOCZojULtFq/Pnlxh9lI8QfcDIBvNx6zuUvx1SG01g4x00BaxyrYLeR6sZGjCOV49Q", - "AR8Cln9xwAipAotEerjb6FQ+XyWOxg2QUgURf48mYgfNM0yEJ/gmVfCEfCvaaTvD9X2LSirK94q3qALy", - "4k3K3GpzRvmfL9gyFOJv2ha+W3a6T08X/CQCDKPN+FdKzqQ6Rn2YVUYz0gRnXO9vFXzeYvuLVFGrkFod", - "jBtETtBRW2SMJIYY3knDNdGIavXwqBiJoYI9RiqdHhbLxVIU+oBOBwMNrPJRBUHzNk9Ty3z1MSCvuyQH", - "Q4lKyLUoWnfQwFdkiVDunSU0z0cwQiO9oJrihNwJLk3gOGI1LfGMgWkjYAreUQnkcbksO+0YXRajQ9iZ", - "NsupX0hmO170+xixhwY+1P9eTT09mVpUZ6+vPd7rnekk2pwXjdbqeChzyqkazB6dMh06Nr3BuMi47FWT", - "72rOqxs88W2CPyZE3h2oXnl5qj6VoviExJ98d3jPqcvWp+t1lCTSf7p9fgdv2n7zMu7HQJBrvR53/G4u", - "lN/KGdrR4Z+ALWOncMJcLsF1fCml9DcAAP//Z6kfG5EFAAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "rFQ9b9swEP0rxLWjYDnxprFFUXgpMhRdAg+sdJKZmh/lnYwaBv97caTs2rGMDM0Uhfd47917Rx+h9TZ4", + "h44JmiNQu0Wr8+eXGH2UjxB9wMgG83HrO5S/HVIbTWDjHTQFrHKtgt5HqxkaMI5Xj1ABHwKWf3HACKkC", + "i0R6uNvoVD5fJY7GDZBSBRF/jyZiB80zTIQn+CZV8IR8K9ppO8P1fYtKKsr3ireoAvLiTcrcanNG+Z8v", + "2DIU4m/aFr5bdrpPTxf8JAIMo834V0rOpDpGfZhVRjPSBGdc728VfN5i+4tUUauQWh2MG0RO0FFbZIwk", + "hhjeScM10Yhq9fCoGImhgj1GKp0eFsvFUhT6gE4HAw2s8lEFQfM2T1PLfPUxIK+7JAdDiUrItShad9DA", + "V2SJUO6dJTTPRzBCI72gmuKE3AkuTeA4YjUt8YyBaSNgCt5RCeRxuSw77RhdFqND2Jk2y6lfSGY7XvT7", + "GLGHBj7U/15NPT2ZWlRnr6893uud6STanBeN1up4KHPKqRrMHp0yHTo2vcG4yLjsVZPvas6rGzzxbYI/", + "JkTeHaheeXmqPpWi+ITEn3x3eM+py9an63WUJNJ/un1+B2/afvMy7sdAkGu9Hnf8bi6U38oZ2tHhn4At", + "Y6dwwlwuwXV8KaX0NwAA//8=", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -563,7 +565,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -581,12 +583,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -612,3 +614,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go index 07fd1b0a14..9fb77c6726 100644 --- a/internal/test/issues/issue-52/issue.gen.go +++ b/internal/test/issues/issue-52/issue.gen.go @@ -5,7 +5,7 @@ package issue52 import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -334,32 +334,34 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/5RSwU7rMBD8lWjfO0ZJXt/NNyQQQgjBiROXxd42Lo5t2ZuKqsq/o3XaQgQCcYo92Zmd", - "He8BdBhi8OQ5gzpA1j0NWI4XKeH+Ed1IcrNMQ4H/JlqDgj/tO7E9stq5eqqB95FAAYqE3C+DHgfyLAIx", - "hUiJLRW5tSVnygmNsWyDR/ewqPhNw/C8Jc0wfUZqOI+yNICLMb9r9iGQqYbMyfrNmXhsN6NfGRDI+nWQ", - "YkNZJxtlWlBwhy9U5TFRxT1ylUiPKdsdVaKQK0xU9eiNI1PN1t3+yUMNbNlJB3rFITqCGnaU8qzZNV3z", - "T2yGSB6jBQX/m65ZQQ0RuS+TtyeiOsCGytuIOoqtGwMKrub/18RQQ6Icg89zaKuuk48Ono+vijE6qwu3", - "3WbxcFqmn2I970aJaBnN/a2g0zS9BQAA//+hEzLlqAIAAA==", + "lFLBTuswEPyVaN87Rkle3803JBBCCMGJE5fF3jYujm3Zm4qqyr+jddpCBAJxij3ZmZ0d7wF0GGLw5DmD", + "OkDWPQ1Yjhcp4f4R3Uhys0xDgf8mWoOCP+07sT2y2rl6qoH3kUABioTcL4MeB/IsAjGFSIktFbm1JWfK", + "CY2xbINH97Co+E3D8LwlzTB9Rmo4j7I0gIsxv2v2IZCphszJ+s2ZeGw3o18ZEMj6dZBiQ1knG2VaUHCH", + "L1TlMVHFPXKVSI8p2x1VopArTFT16I0jU83W3f7JQw1s2UkHesUhOoIadpTyrNk1XfNPbIZIHqMFBf+b", + "rllBDRG5L5O3J6I6wIbK24g6iq0bAwqu5v/XxFBDohyDz3Noq66Tjw6ej6+KMTqrC7fdZvFwWqafYj3v", + "RoloGc39raDTNL0FAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -367,7 +369,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -385,12 +387,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -416,3 +418,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-832/issue.gen.go b/internal/test/issues/issue-832/issue.gen.go index 4a5aa56a3d..8b0d1e2123 100644 --- a/internal/test/issues/issue-832/issue.gen.go +++ b/internal/test/issues/issue-832/issue.gen.go @@ -5,7 +5,7 @@ package issue_832 import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -53,32 +53,34 @@ type DocumentStatus struct { Value *string `json:"value,omitempty"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/7ySz0/rMAzH/5XK7x27tq/vljMIIYQ47AgIhdRbM9o4Styxaer/jpxuReOHxIlL4zq2", - "vx/HPoCh3pNDxxHUAaJpsdfJvCAz9OhYbB/IY2CL6cbpHuXkvUdQEDlYt4Yxh8iahxSCbuhB3QM5hBz4", - "leTbBpS/FQ0BHvMP6TnsFmtaiHMxCcwET8up7jjOSfS8QcOieQpaztrnsFvdDV/Rfq4lLutWJMENRhOs", - "Z0sOFNzqF8ziEDDjVnMW0Awh2i1mUiFmOmDWatd02GSTeLd/cNKx5U4UcKd730nvWwxxqlkVVfFPGiCP", - "TnsLCv4XVVFDDl5zm9jLU6I6wBrTJKS6FqzrBhRcTvdXyJBDwOjJxantuqrkMOT4OEPtfWdNyi03URhO", - "4xbrb8AVKPhTvu9DeVyGct6E9ETnT3N3I94xn1nrH8DWv0E7L813zOP4FgAA//8tucJ2/gIAAA==", + "vJLPT+swDMf/lcrvHbu2r++WMwghhDjsCAiF1Fsz2jhK3LFp6v+OnG5F44fEiUvjOra/H8c+gKHek0PH", + "EdQBommx18m8IDP06FhsH8hjYIvpxuke5eS9R1AQOVi3hjGHyJqHFIJu6EHdAzmEHPiV5NsGlL8VDQEe", + "8w/pOewWa1qIczEJzARPy6nuOM5J9LxBw6J5ClrO2uewW90NX9F+riUu61YkwQ1GE6xnSw4U3OoXzOIQ", + "MONWcxbQDCHaLWZSIWY6YNZq13TYZJN4t39w0rHlThRwp3vfSe9bDHGqWRVV8U8aII9OewsK/hdVUUMO", + "XnOb2MtTojrAGtMkpLoWrOsGFFxO91fIkEPA6MnFqe26quQw5Pg4Q+19Z03KLTdRGE7jFutvwBUo+FO+", + "70N5XIZy3oT0ROdPc3cj3jGfWesfwNa/QTsvzXfM4/gWAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -86,7 +88,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -104,12 +106,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -135,3 +137,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go index 32cf049063..480b01aca8 100644 --- a/internal/test/issues/issue-grab_import_names/issue.gen.go +++ b/internal/test/issues/issue-grab_import_names/issue.gen.go @@ -5,7 +5,7 @@ package grabimportnames import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -391,32 +391,33 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/3yRzWrrQAyFX0VoPSgmudyFl6W0dN9dKWXiKPEUzw+SUpIGv3uZcVahqTdCwvrm6JwL", - "hrTP2F/Qgk2MPRIROvxi0ZAT9thRRx3ODnPh5EvAHjfU0RodFm+j1t3VPjfGga2WHesgodgCWIC5sPg6", - "edlhj89sTzk3hPjIxqLYv91ubr3y/38E27OxEgxjIBhyMj4ZAQ9jJmCRLEqwj0Zw+A6FYDQrBCETfGpO", - "BFfdm6oiVOzIfseCDpOP9eJFiQ4jR9+cOJc6VpOQDjjP7lbXlfhRf1SCagOBHJOFyATLnhK09vG4nL10", - "ryEyHGUiOMWJ4OzjdFfWg5c/Zb07FNaSk3ILYd11tTSDUsvBlzKFoT2/ql7U2X3e7H4Jbm7fTwAAAP//", - "VfuleiYCAAA=", + "fJHNautADIVfRWg9KCa53IWXpbR0310pZeIo8RTPD5JSkga/e5lxVqGpN0LC+ubonAuGtM/YX9CCTYw9", + "EhE6/GLRkBP22FFHHc4Oc+HkS8AeN9TRGh0Wb6PW3dU+N8aBrZYd6yCh2AJYgLmw+Dp52WGPz2xPOTeE", + "+MjGoti/3W5uvfL/fwTbs7ESDGMgGHIyPhkBD2MmYJEsSrCPRnD4DoVgNCsEIRN8ak4EV92bqiJU7Mh+", + "x4IOk4/14kWJDiNH35w4lzpWk5AOOM/uVteV+FF/VIJqA4Eck4XIBMueErT28bicvXSvITIcZSI4xYng", + "7ON0V9aDlz9lvTsU1pKTcgth3XW1NINSy8GXMoWhPb+qXtTZfd7sfglubt9PAAAA//8=", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -424,7 +425,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -442,12 +443,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -473,3 +474,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go index 11a39afe9e..e5f45d16b1 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go +++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go @@ -5,7 +5,7 @@ package illegalenumnames import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -365,31 +365,32 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/0xQQU4DMQz8SjVwDNml3HLkUMQbEKqirbcN6tpRYpCqKn9HzkIhl5kkHtszV0yyZGFi", - "rQhX1OlES+z0ORYD4s8F4Q1w2InA9ffONzf2sLLH/wWb9WKwgcN+J7K3Grw76CUTAqqWxEe01hwSz2Lj", - "NOnZ/rz3cPiiUpMwAkY/+hHNQTJxzAkBT370WzjkqKe+8TBL73EkNZBMJWoSfj0g4IV03ahQzcKVumQ7", - "jgaTsBJ3Vcz5nKauGz6qzf5NxVhSWrrwvtCMgLvhL7/hJ7zBAmg3l7GUeFlNHqhOJWVdLZnF1s93AAAA", - "//9U8KAOhgEAAA==", + "TFBBTgMxDPxKNXAM2aXccuRQxBsQqqKttw3q2lFikKoqf0fOQiGXmSQe2zNXTLJkYWKtCFfU6URL7PQ5", + "FgPizwXhDXDYicD19843N/awssf/BZv1YrCBw34nsrcavDvoJRMCqpbER7TWHBLPYuM06dn+vPdw+KJS", + "kzACRj/6Ec1BMnHMCQFPfvRbOOSop77xMEvvcSQ1kEwlahJ+PSDghXTdqFDNwpW6ZDuOBpOwEndVzPmc", + "pq4bPqrN/k3FWFJauvC+0IyAu+Evv+EnvMECaDeXsZR4WU0eqE4lZV0tmcXWz3cAAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -397,7 +398,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -415,12 +416,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -446,3 +447,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue-illegal_enum_names/issue_test.go b/internal/test/issues/issue-illegal_enum_names/issue_test.go index 77d4eb416c..22f3cb3d26 100644 --- a/internal/test/issues/issue-illegal_enum_names/issue_test.go +++ b/internal/test/issues/issue-illegal_enum_names/issue_test.go @@ -33,15 +33,19 @@ func TestIllegalEnumNames(t *testing.T) { constDefs := make(map[string]string) for _, d := range f.Decls { - switch decl := d.(type) { - case *ast.GenDecl: - if token.CONST == decl.Tok { - for _, s := range decl.Specs { - switch spec := s.(type) { - case *ast.ValueSpec: - constDefs[spec.Names[0].Name] = spec.Names[0].Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value - } - } + decl, ok := d.(*ast.GenDecl) + if !ok || decl.Tok != token.CONST { + continue + } + + for _, s := range decl.Specs { + spec, ok := s.(*ast.ValueSpec) + if !ok { + continue + } + + if v, ok := spec.Names[0].Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit); ok { + constDefs[spec.Names[0].Name] = v.Value } } } diff --git a/internal/test/issues/issue1825/issue1825.gen.go b/internal/test/issues/issue1825/issue1825.gen.go index 679963f84c..c8c5a18a5b 100644 --- a/internal/test/issues/issue1825/issue1825.gen.go +++ b/internal/test/issues/issue1825/issue1825.gen.go @@ -5,7 +5,7 @@ package issue1825 import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -22,30 +22,32 @@ type Container struct { ObjectB *map[string]interface{} `json:"object_b,omitempty"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4SP0U7DMAxF/8Xw2K2TeOvbxAfAH1Re6m2G1rESd2Ka8u/IWQcIkPaUWNf33OsLhDhp", - "FBLL0F0ghyNNWL/PUQxZKPmgKSolY6pS3L1RsB79/5hoDx08tN+gdqG0iuEdD7Tts1LoX6prC6W5AXb3", - "AF97pfxy4TCwcRQcX39UszRTA3ZWgm5Z97j/e/w5S3Aifxd/tsRy8GgPZ9nHKrKNrkIDJ0qZo1yHj1U8", - "URrxvELVkWm4EuZgc6LhJtbjlQSVoYOn9Wa9Ae9nR29QymcAAAD//5P9oGCQAQAA", + "hI/RTsMwDEX/xfDYrZN469vEB8AfVF7qbYbWsRJ3Ypry78hZBwiQ9pRY1/fc6wuEOGkUEsvQXSCHI01Y", + "v89RDFko+aApKiVjqlLcvVGwHv3/mGgPHTy036B2obSK4R0PtO2zUuhfqmsLpbkBdvcAX3ul/HLhMLBx", + "FBxff1SzNFMDdlaCbln3uP97/DlLcCJ/F3+2xHLwaA9n2ccqso2uQgMnSpmjXIePVTxRGvG8QtWRabgS", + "5mBzouEm1uOVBJWhg6f1Zr0B72dHb1DKZwAAAP//", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -53,7 +55,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -77,12 +79,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -108,3 +110,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/issues/issue1825/overlay_test.go b/internal/test/issues/issue1825/overlay_test.go index 115a878fad..75cd428323 100644 --- a/internal/test/issues/issue1825/overlay_test.go +++ b/internal/test/issues/issue1825/overlay_test.go @@ -7,7 +7,7 @@ import ( ) func TestOverlayApply(t *testing.T) { - spec, err := GetSwagger() + spec, err := GetSpec() require.NoError(t, err) require.Equal(t, spec.Info.Extensions["x-overlay-applied"], "structured-overlay") diff --git a/internal/test/issues/issue1825/packageA/externalref.gen.go b/internal/test/issues/issue1825/packageA/externalref.gen.go index b2d5ca870b..d222870d82 100644 --- a/internal/test/issues/issue1825/packageA/externalref.gen.go +++ b/internal/test/issues/issue1825/packageA/externalref.gen.go @@ -5,7 +5,7 @@ package packagea import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "fmt" "net/url" @@ -20,28 +20,30 @@ type ObjectA struct { Name *string `json:"name,omitempty"` } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/yTJwQ0CMQxE0V7mnApyowJqCNHAGm1sKzYHtNreUZa5zJfegW7DTakZqAeibxztyvvj", - "zZ63lT7NOVN4gbbB9fl1oiJyir5wrhWIPg1VP/teYE5tLqhAgbfc4i/nLwAA//+kHCeTdgAAAA==", + "JMnBDQIxDETRXuacCnKjAmoI0cAabWwrNge02t5RlrnMl96BbsNNqRmoB6JvHO3K++PNnreVPs05U3iB", + "tsH1+XWiInKKvnCuFYg+DVU/+15gTm0uqECBt9ziL+cvAAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -49,7 +51,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -67,12 +69,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -98,3 +100,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go index e27de44070..5e5d1f4d81 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-additional-initialisms/name_normalizer.gen.go @@ -5,7 +5,7 @@ package tocamelcasewithadditionalinitialisms import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -512,35 +512,36 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RTTW/bPAz+KwLf96jZWXrzvdh6WXvIrQgQzaJtFrakSXSwLvB/HyglWZZk6CWRRerR", - "8yEeoPVT8A4dJ2gOkNoBJ5OXjzH6KIsQfcDIhHm79Rbl32JqIwUm76ApzSrXNHQ+ToahAXL8sAYN/B6w", - "fGKPERYNE6Zk+n8Cncrno4kjuR6WRUPEHzNFtNC8wvHCU/t20fDs8Llb80CuT7fw3zxTi4oHw4oHVLvS", - "uFOUlPOsWhOIzUgJLWjwggXN67UHZOX3WtUVN7KwPfP339+wZVj0faizY/NM9kPVd5FF+wvybWDOTHd8", - "3gyopKJ8l40IyNXtxboQuns6ICupVh/yPYrKRG6JSze5zmdLiUepPf40UxgxPyjV+ViyEoBPTqwa6RfG", - "nfIzh5mVL7Q07DGmQvBztapWwt8HdCYQNPCQtzQEw0M2pjaB6oCc6kNAfrKLbPbFQjHQCOqThQa+IH/d", - "bF7EXjkfzYSMMeWXQXKdYJ4UNpDR4NIDjjPq43BdPJ2zX1tpTsG7VDJbr1Zl1hyjy4RMCCO1mVL9lkTj", - "4QLv/4gdNPBf/Wea6+Mo18I6m/x3hHszkpUQc1xpniYT34vWHG1Pe3SKLDqmjjBWArL8DgAA//+VcR3v", - "MAQAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "hFNNb9s8DP4rAt/3qNlZevO92HpZe8itCBDNom0WtqRJdLAu8H8fKCVZlmToJZFF6tHzIR6g9VPwDh0n", + "aA6Q2gEnk5ePMfooixB9wMiEebv1FuXfYmojBSbvoCnNKtc0dD5OhqEBcvywBg38HrB8Yo8RFg0TpmT6", + "fwKdyuejiSO5HpZFQ8QfM0W00LzC8cJT+3bR8OzwuVvzQK5Pt/DfPFOLigfDigdUu9K4U5SU86xaE4jN", + "SAktaPCCBc3rtQdk5fda1RU3srA98/ff37BlWPR9qLNj80z2Q9V3kUX7C/JtYM5Md3zeDKikonyXjQjI", + "1e3FuhC6ezogK6lWH/I9ispEbolLN7nOZ0uJR6k9/jRTGDE/KNX5WLISgE9OrBrpF8ad8jOHmZUvtDTs", + "MaZC8HO1qlbC3wd0JhA08JC3NATDQzamNoHqgJzqQ0B+sots9sVCMdAI6pOFBr4gf91sXsReOR/NhIwx", + "5ZdBcp1gnhQ2kNHg0gOOM+rjcF08nbNfW2lOwbtUMluvVmXWHKPLhEwII7WZUv2WROPhAu//iB008F/9", + "Z5rr4yjXwjqb/HeEezOSlRBzXGmeJhPfi9YcbU97dIosOqaOMFYCsvwOAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -548,7 +549,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -566,12 +567,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -597,3 +598,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go index 0b361107a4..ee65dae6ac 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-digits/name_normalizer.gen.go @@ -5,7 +5,7 @@ package tocamelcasewithdigits import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -512,35 +512,36 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RTzY7TMBB+FWvgaJLSveW+gr2wHLitKtXEk2RWiW3sScVS5d3R2G0pbVe9tI5n/Pn7", - "8eyh9VPwDh0naPaQ2gEnk5ePMfooixB9wMiEebv1FuXfYmojBSbvoCnNKtc0dD5OhqEBcvywBg38FrB8", - "Yo8RFg0TpmT6d4GO5dPRxJFcD8uiIeKvmSJaaF7gcOGxfbNoeHb43K15INena/hvnqlFxYNhxQOqbWnc", - "KkrKeVatCcRmpIQWNHjBgubl0gOy8nup6oIbWdic+Pufr9gyLPo21MmxeSZ7V/VNZNH+Hfk6MGemGz7/", - "GFBJRfkuGxGQq+uLdSF083RAVlKt7vI9iMpErolLN7nOZ0uJR6k9/jZTGDE/KNX5WLISgE9OrBrpD8at", - "8jOHmZUvtDTsMKZC8HO1qlbC3wd0JhA08JC3NATDQzamNoHqgJzqfUB+sots9sVCMdAI6pOFBr4gf2UO", - "Yq+cj2ZCxpjyyyC5TjCPChvIaHDuAccZ9WG4zp7Oya+NNKfgXSqZrVerMmuO0WVCJoSR2kypfk2icX+G", - "9zFiBw18qP9Nc30Y5VpYZ5P/j3BnRrISYo4rzdNk4lvRmqPtaYdOkUXH1BHGSkCWvwEAAP//D5F1qDAE", - "AAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "hFPNjtMwEH4Va+BoktK95b6CvbAcuK0q1cSTZFaJbexJxVLl3dHYbSltV720jmf8+fvx7KH1U/AOHSdo", + "9pDaASeTl48x+iiLEH3AyIR5u/UW5d9iaiMFJu+gKc0q1zR0Pk6GoQFy/LAGDfwWsHxijxEWDROmZPp3", + "gY7l09HEkVwPy6Ih4q+ZIlpoXuBw4bF9s2h4dvjcrXkg16dr+G+eqUXFg2HFA6ptadwqSsp5Vq0JxGak", + "hBY0eMGC5uXSA7Lye6nqghtZ2Jz4+5+v2DIs+jbUybF5JntX9U1k0f4d+TowZ6YbPv8YUElF+S4bEZCr", + "64t1IXTzdEBWUq3u8j2IykSuiUs3uc5nS4lHqT3+NlMYMT8o1flYshKAT06sGukPxq3yM4eZlS+0NOww", + "pkLwc7WqVsLfB3QmEDTwkLc0BMNDNqY2geqAnOp9QH6yi2z2xUIx0Ajqk4UGviB/ZQ5ir5yPZkLGmPLL", + "ILlOMI8KG8hocO4Bxxn1YbjOns7Jr400p+BdKpmtV6sya47RZUImhJHaTKl+TaJxf4b3MWIHDXyo/01z", + "fRjlWlhnk/+PcGdGshJijivN02TiW9Gao+1ph06RRcfUEcZKQJa/AQAA//8=", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -548,7 +549,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -566,12 +567,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -597,3 +598,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go index f69341bea8..6d924715f5 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case-with-initialisms/name_normalizer.gen.go @@ -5,7 +5,7 @@ package tocamelcasewithinitialisms import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -512,35 +512,36 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RTTW/bPAz+KwLf96jZWXrzvdh6WXvIrQgQzaJtFrakSXSwLvB/HyglWZZk6CWRRerR", - "8yEeoPVT8A4dJ2gOkNoBJ5OXjzH6KIsQfcDIhHm79Rbl32JqIwUm76ApzSrXNHQ+ToahAXL8sAYN/B6w", - "fGKPERYNE6Zk+n8Cncrno4kjuR6WRUPEHzNFtNC8wvHCU/t20fDs8Llb80CuT7fw3zxTi4oHw4oHVLvS", - "uFOUlPOsWhOIzUgJLWjwggXN67UHZOX3WtUVN7KwPfP339+wZVj0faizY/NM9kPVd5FF+wvybWDOTHd8", - "3gyopKJ8l40IyNXtxboQuns6ICupVh/yPYrKRG6JSze5zmdLiUepPf40UxgxPyjV+ViyEoBPTqwa6RfG", - "nfIzh5mVL7Q07DGmQvBztapWwt8HdCYQNPCQtzQEw0M2pjaB6oCc6kNAfrKLbPbFQjHQCOqThQa+IH/d", - "bF7EXjkfzYSMMeWXQXKdYJ4UNpDR4NIDjjPq43BdPJ2zX1tpTsG7VDJbr1Zl1hyjy4RMCCO1mVL9lkTj", - "4QLv/4gdNPBf/Wea6+Mo18I6m/x3hHszkpUQc1xpniYT34vWHG1Pe3SKLDqmjjBWArL8DgAA//+VcR3v", - "MAQAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "hFNNb9s8DP4rAt/3qNlZevO92HpZe8itCBDNom0WtqRJdLAu8H8fKCVZlmToJZFF6tHzIR6g9VPwDh0n", + "aA6Q2gEnk5ePMfooixB9wMiEebv1FuXfYmojBSbvoCnNKtc0dD5OhqEBcvywBg38HrB8Yo8RFg0TpmT6", + "fwKdyuejiSO5HpZFQ8QfM0W00LzC8cJT+3bR8OzwuVvzQK5Pt/DfPFOLigfDigdUu9K4U5SU86xaE4jN", + "SAktaPCCBc3rtQdk5fda1RU3srA98/ff37BlWPR9qLNj80z2Q9V3kUX7C/JtYM5Md3zeDKikonyXjQjI", + "1e3FuhC6ezogK6lWH/I9ispEbolLN7nOZ0uJR6k9/jRTGDE/KNX5WLISgE9OrBrpF8ad8jOHmZUvtDTs", + "MaZC8HO1qlbC3wd0JhA08JC3NATDQzamNoHqgJzqQ0B+sots9sVCMdAI6pOFBr4gf91sXsReOR/NhIwx", + "5ZdBcp1gnhQ2kNHg0gOOM+rjcF08nbNfW2lOwbtUMluvVmXWHKPLhEwII7WZUv2WROPhAu//iB008F/9", + "Z5rr4yjXwjqb/HeEezOSlRBzXGmeJhPfi9YcbU97dIosOqaOMFYCsvwOAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -548,7 +549,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -566,12 +567,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -597,3 +598,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go index b79d538332..e9913ca86c 100644 --- a/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/to-camel-case/name_normalizer.gen.go @@ -5,7 +5,7 @@ package tocamelcase import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -512,35 +512,36 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RTzY7TMBB+FWvgaJLSveW+gr2wHLitKtXEk2RWiW3sScVS5d3R2G0pbVe9tI5n/Pn7", - "8eyh9VPwDh0naPaQ2gEnk5ePMfooixB9wMiEebv1FuXfYmojBSbvoCnNKtc0dD5OhqEBcvywBg38FrB8", - "Yo8RFg0TpmT6d4GO5dPRxJFcD8uiIeKvmSJaaF7gcOGxfbNoeHb43K15INena/hvnqlFxYNhxQOqbWnc", - "KkrKeVatCcRmpIQWNHjBgubl0gOy8nup6oIbWdic+Pufr9gyLPo21MmxeSZ7V/VNZNH+Hfk6MGemGz7/", - "GFBJRfkuGxGQq+uLdSF083RAVlKt7vI9iMpErolLN7nOZ0uJR6k9/jZTGDE/KNX5WLISgE9OrBrpD8at", - "8jOHmZUvtDTsMKZC8HO1qlbC3wd0JhA08JC3NATDQzamNoHqgJzqfUB+sots9sVCMdAI6pOFBr4gf2UO", - "Yq+cj2ZCxpjyyyC5TjCPChvIaHDuAccZ9WG4zp7Oya+NNKfgXSqZrVerMmuO0WVCJoSR2kypfk2icX+G", - "9zFiBw18qP9Nc30Y5VpYZ5P/j3BnRrISYo4rzdNk4lvRmqPtaYdOkUXH1BHGSkCWvwEAAP//D5F1qDAE", - "AAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "hFPNjtMwEH4Va+BoktK95b6CvbAcuK0q1cSTZFaJbexJxVLl3dHYbSltV720jmf8+fvx7KH1U/AOHSdo", + "9pDaASeTl48x+iiLEH3AyIR5u/UW5d9iaiMFJu+gKc0q1zR0Pk6GoQFy/LAGDfwWsHxijxEWDROmZPp3", + "gY7l09HEkVwPy6Ih4q+ZIlpoXuBw4bF9s2h4dvjcrXkg16dr+G+eqUXFg2HFA6ptadwqSsp5Vq0JxGak", + "hBY0eMGC5uXSA7Lye6nqghtZ2Jz4+5+v2DIs+jbUybF5JntX9U1k0f4d+TowZ6YbPv8YUElF+S4bEZCr", + "64t1IXTzdEBWUq3u8j2IykSuiUs3uc5nS4lHqT3+NlMYMT8o1flYshKAT06sGukPxq3yM4eZlS+0NOww", + "pkLwc7WqVsLfB3QmEDTwkLc0BMNDNqY2geqAnOp9QH6yi2z2xUIx0Ajqk4UGviB/ZQ5ir5yPZkLGmPLL", + "ILlOMI8KG8hocO4Bxxn1YbjOns7Jr400p+BdKpmtV6sya47RZUImhJHaTKl+TaJxf4b3MWIHDXyo/01z", + "fRjlWlhnk/+PcGdGshJijivN02TiW9Gao+1ph06RRcfUEcZKQJa/AQAA//8=", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -548,7 +549,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -566,12 +567,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -597,3 +598,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go index 4e8b5399cd..b511d10eb3 100644 --- a/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go +++ b/internal/test/outputoptions/name-normalizer/unset/name_normalizer.gen.go @@ -5,7 +5,7 @@ package unset import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -512,35 +512,36 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/4RTzY7TMBB+FWvgaJLSveW+gr2wHLitKtXEk2RWiW3sScVS5d3R2G0pbVe9tI5n/Pn7", - "8eyh9VPwDh0naPaQ2gEnk5ePMfooixB9wMiEebv1FuXfYmojBSbvoCnNKtc0dD5OhqEBcvywBg38FrB8", - "Yo8RFg0TpmT6d4GO5dPRxJFcD8uiIeKvmSJaaF7gcOGxfbNoeHb43K15INena/hvnqlFxYNhxQOqbWnc", - "KkrKeVatCcRmpIQWNHjBgubl0gOy8nup6oIbWdic+Pufr9gyLPo21MmxeSZ7V/VNZNH+Hfk6MGemGz7/", - "GFBJRfkuGxGQq+uLdSF083RAVlKt7vI9iMpErolLN7nOZ0uJR6k9/jZTGDE/KNX5WLISgE9OrBrpD8at", - "8jOHmZUvtDTsMKZC8HO1qlbC3wd0JhA08JC3NATDQzamNoHqgJzqfUB+sots9sVCMdAI6pOFBr4gf2UO", - "Yq+cj2ZCxpjyyyC5TjCPChvIaHDuAccZ9WG4zp7Oya+NNKfgXSqZrVerMmuO0WVCJoSR2kypfk2icX+G", - "9zFiBw18qP9Nc30Y5VpYZ5P/j3BnRrISYo4rzdNk4lvRmqPtaYdOkUXH1BHGSkCWvwEAAP//D5F1qDAE", - "AAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "hFPNjtMwEH4Va+BoktK95b6CvbAcuK0q1cSTZFaJbexJxVLl3dHYbSltV720jmf8+fvx7KH1U/AOHSdo", + "9pDaASeTl48x+iiLEH3AyIR5u/UW5d9iaiMFJu+gKc0q1zR0Pk6GoQFy/LAGDfwWsHxijxEWDROmZPp3", + "gY7l09HEkVwPy6Ih4q+ZIlpoXuBw4bF9s2h4dvjcrXkg16dr+G+eqUXFg2HFA6ptadwqSsp5Vq0JxGak", + "hBY0eMGC5uXSA7Lye6nqghtZ2Jz4+5+v2DIs+jbUybF5JntX9U1k0f4d+TowZ6YbPv8YUElF+S4bEZCr", + "64t1IXTzdEBWUq3u8j2IykSuiUs3uc5nS4lHqT3+NlMYMT8o1flYshKAT06sGukPxq3yM4eZlS+0NOww", + "pkLwc7WqVsLfB3QmEDTwkLc0BMNDNqY2geqAnOp9QH6yi2z2xUIx0Ajqk4UGviB/ZQ5ir5yPZkLGmPLL", + "ILlOMI8KG8hocO4Bxxn1YbjOns7Jr400p+BdKpmtV6sya47RZUImhJHaTKl+TaJxf4b3MWIHDXyo/01z", + "fRjlWlhnk/+PcGdGshJijivN02TiW9Gao+1ph06RRcfUEcZKQJa/AQAA//8=", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -548,7 +549,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -566,12 +567,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -597,3 +598,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/chi/gen/server.gen.go b/internal/test/parameters/chi/gen/server.gen.go index e191f7959c..a32748c70d 100644 --- a/internal/test/parameters/chi/gen/server.gen.go +++ b/internal/test/parameters/chi/gen/server.gen.go @@ -5,7 +5,7 @@ package chiparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "errors" @@ -1563,48 +1563,50 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1612,7 +1614,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1630,12 +1632,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1661,3 +1663,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/echo/gen/server.gen.go b/internal/test/parameters/echo/gen/server.gen.go index ee44e88832..f55c138151 100644 --- a/internal/test/parameters/echo/gen/server.gen.go +++ b/internal/test/parameters/echo/gen/server.gen.go @@ -5,7 +5,7 @@ package echoparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "fmt" @@ -896,48 +896,50 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -945,7 +947,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -963,12 +965,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -994,3 +996,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/echov5/server.gen.go b/internal/test/parameters/echov5/server.gen.go index 46a5ed2ad7..fa9568f23f 100644 --- a/internal/test/parameters/echov5/server.gen.go +++ b/internal/test/parameters/echov5/server.gen.go @@ -5,7 +5,7 @@ package echov5params import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "fmt" @@ -896,48 +896,50 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -945,7 +947,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -963,12 +965,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -994,3 +996,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/fiber/gen/server.gen.go b/internal/test/parameters/fiber/gen/server.gen.go index a615749192..0557bc8fab 100644 --- a/internal/test/parameters/fiber/gen/server.gen.go +++ b/internal/test/parameters/fiber/gen/server.gen.go @@ -5,7 +5,7 @@ package fiberparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "fmt" @@ -1330,48 +1330,50 @@ func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, option } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1379,7 +1381,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1397,12 +1399,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1428,3 +1430,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/gin/gen/server.gen.go b/internal/test/parameters/gin/gen/server.gen.go index 257d7106e0..5bf8e4232f 100644 --- a/internal/test/parameters/gin/gen/server.gen.go +++ b/internal/test/parameters/gin/gen/server.gen.go @@ -5,7 +5,7 @@ package ginparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "fmt" @@ -1193,48 +1193,50 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.GET(options.BaseURL+"/startingWithNumber/:1param", wrapper.GetStartingWithNumber) } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1242,7 +1244,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1260,12 +1262,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1291,3 +1293,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/gorilla/gen/server.gen.go b/internal/test/parameters/gorilla/gen/server.gen.go index b528089ecb..489209ea0a 100644 --- a/internal/test/parameters/gorilla/gen/server.gen.go +++ b/internal/test/parameters/gorilla/gen/server.gen.go @@ -5,7 +5,7 @@ package gorillaparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "errors" @@ -1396,48 +1396,50 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H return r } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1445,7 +1447,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1463,12 +1465,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1494,3 +1496,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/iris/gen/server.gen.go b/internal/test/parameters/iris/gen/server.gen.go index eff396ab5a..2da66aeedf 100644 --- a/internal/test/parameters/iris/gen/server.gen.go +++ b/internal/test/parameters/iris/gen/server.gen.go @@ -5,7 +5,7 @@ package irisparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "fmt" @@ -1032,48 +1032,50 @@ func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, o router.Build() } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1081,7 +1083,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1099,12 +1101,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1130,3 +1132,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/parameters/stdhttp/gen/server.gen.go b/internal/test/parameters/stdhttp/gen/server.gen.go index 06afd09a22..eda0976432 100644 --- a/internal/test/parameters/stdhttp/gen/server.gen.go +++ b/internal/test/parameters/stdhttp/gen/server.gen.go @@ -7,7 +7,7 @@ package stdhttpparamsgen import ( "bytes" - "compress/gzip" + "compress/flate" "encoding/base64" "encoding/json" "errors" @@ -1378,48 +1378,50 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H return m } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/9xaS2/jNhf9K8L9vlWhWHamK3UVTKdtgE4mrQNMgSALRrqOOJVEDkmnCQz994KUZD2t", - "hy3l0V1iXd7HIc+heKkdeCziLMZYSXB3IFByFks0/6xpxEP8M/tJ/+KxWGGs9J8Kn5TDQ0Jj/Z/0AoyI", - "+f2ZI7gglaDxAyRJYoOP0hOUK8picOHCksavlcey2P039BRo09SPif6RaaunL+lDdwdcMI5C0TS5S78U", - "jcYKH1BAYsOlvPCjNKns4T1jIZJYPyyc/V/gBlz4n1PU72TBnS9FPgK/b6lAH9zbfLCtQxdx7ipuqzlu", - "qJDqikTYAowNgoVtD2pRjZVdcnVnMKXxhunBIfUwm5zYBILPlzfau6JKu4cblMpao3hEATY8opDpNKwW", - "y8VSGzKOMeEUXPiwWC5WYAMnKjD5O9l8p/U5O04EiRL95AFNubpYoudVzwb8iupjeYBxJUiECoUE97ay", - "fgjnIfXMYOebZLVV1DU91YWRoQGuSRvsHAYTGcpYKrHF5M6urvHz5fJQvL2dUyNCYmI6HmN/U+xGw1g0", - "YKgSggsaUUUftSE+8ZD5CO6GhBKzwrzcTV4a2CWoNkxERKUk+HAOdoMTiT0ooobnQEA8OWIWxbeIEOR5", - "aFhSCUsVRnJQ/P0vabSWfBppdOE9Xxp7WFhOmEG4sEpCw6SsHroZsQuC4yLORfdqJV5qUGDYWoHHoAmC", - "fmZJRYSi8YP1D1WBFW+jeyOVrV5WsgJEXbrr6uLjhmxDdazCYLxNl1qrwHyKt9G1FhbZpzDX+cO0RO3W", - "eiThFmVe5/ctiufSCjOuVXCdiWhRsX4C7u1qubTPl8s7e4AYNCX3xxSbykwwK18tWfEBEh9Fl7z+llqc", - "Kq9B7iYr/q+z69KQWYW2I/TZp0wbXkR6m4lcaOv2JF5MiA9k9cpy3Mwq1aZ2sOZQ50MZvDuRbhaSOcoL", - "OkKy6z5XZ+vM+uwrVcHZVW79YjIeknsMs8VhFrCzWxjJ+qHzXfr3+rCm0rUtzyGvwdMQyAapns0hw1QI", - "U75clzHLjx9jQTt0CpkCtSHseil89nvGeIjKO90MKA1YUjNDdMXaiNePT3VcBzplXf4PUW9ff5V8I4Dr", - "Zd8pyL0J+jV414/OEL6dgsurEi4iStCnGt+o361GnxuDjpEi6s9OtLS6+QDbE20UYsfvcT2QjWPY3OCU", - "qPbTKHxO2uB6IBpBttnwaexv1B8AzgS723tmXHNzG4faCVvb+2BdlW4DoDltX3vTPONEyptAsO1DMOQG", - "5Low77z/GHF/9iq3G6Yj+DMiLy63DpVcsurpxfmIvLu5UmtE+qnrozlT60sUC8Uvcp76uJ8hF2pGoN8F", - "3B9Vyx7wJCceWn5ubnW2zmo4yqnuMAoETTpF8i3NT8qPTZdPn67OppTt1Ez5hYmod6qNUc8sD2rX1tv1", - "08Olh8LIdm0tqxdLaljbto7Z/JdotYhTBNyX2nezUK92njvjLgpPFtDK9sIDcbpv5F65wV1L9rhLyJqT", - "kXeQJyhb+qFO9YAxoMG4bgx7u53rtESYDbXKpzMjYHs7veu5ESqdNfrfrtetI1+9eT0bRvXj/VCE3k37", - "en7khn+8tm4b+CYa2LOhdAT5Olj3HmmW7btfqQrSm2FntxoARWPYjIf91cynfY2w+UA0zXsrQnAhUIq7", - "jpN9HapQqoU+M0eELwiF5C75NwAA///UsxqiOywAAA==", + "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", + "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", + "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", + "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", + "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", + "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", + "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", + "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", + "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", + "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", + "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", + "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", + "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", + "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", + "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", + "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", + "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", + "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", + "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", + "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", + "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", + "R4QvCIXkLvk3AAD//w==", } -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1427,7 +1429,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1445,12 +1447,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1476,3 +1478,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go index d47eea4e87..9568743929 100644 --- a/internal/test/schemas/schemas.gen.go +++ b/internal/test/schemas/schemas.gen.go @@ -5,7 +5,7 @@ package schemas import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1702,52 +1702,54 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/7RYXW/buBL9Kyxvgftw/Z0GbfyW2+0WLrBJ0GTRhzoPtDi22EhDlaTsCIb++2JI2bIj", - "yW02bV5iiZzhmTPDM6S2PNJpphHQWT7d8kwYkYID459unVG4muGNcDE9S7CRUZlTGvmUXzLrx1kmXMz2", - "lrzHFQ3TW97jKFLgU24dDRj4nisDkk+dyaHHbRRDKsi1K7JqmsIVL8tyN+iBnN86YZz9olx8lacLME00", - "d7GyLJgwWpNZb8I2ysVMMAxmvd1CevENIsfLHr/E4q7IYMyn2/pp0hJuNcIMZAYsMcYEFowcDuY4x4Ag", - "1nki2QKYQKbQgVmKCLblHGmt97l1Og203nkgW77UJhWOT3nkB2uIFRc9/tjXIlP9SEtYAfbh0RnRd2Jl", - "g7nmU74QhhNnfxC2SDiQN0ZnYFzhsxp+K/AWCBsabEb4twXmKAjUm1cNHGWP68S7HQfT3Uq7ZHZNn7RP", - "P1575lhuQTKnmdQBhUDJXCzcCSRnP4OECKzn9A0Iuw/3KnDBFFoHQr468P3mV8N+Ho7ycLd83SdtD4/f", - "t9TyB8zTGV4vvs3w0hjhk68cpLZZBWuR0D/APCX/S2UsQbYQaZQHzvc7smW56oXwS5U9/hEQjIquw4R6", - "V9cWV3mSiEUCN0dYjpFpT26A10x8NXiJcufL1/T+d0ct1lxuuwef5/RJhva/2/21pes6d2BIB0jYLlFj", - "kerczhCDwB3TojpeH4ZEgrMC08CmZHN9KseV7tPLfiXSfuXPQE9yD+d6DzfM2v6ABz+rV8FtRl36GsuN", - "csUtqXWIQkQRWNt3+gGQnhcgDJg/d9L46ctdP+gkCzOZnzmYI6/6BC0RjOp9FzuXhVaicKlbWgZYxyJh", - "wbKlNmwtjNK5Zcra3L/KUTK9BsOcSmHAbhIQFpiQkgnmdrZkOkdqBIt8xZbqEWSA5ZSj0gmr3IJZe2hr", - "MDasPh6MBqNQ0oAiU3zKzwajwZj3fOv0tAwBbW6gD2swhYsVrvrK9g0swQBGoZpX4Dq6IaDMtELH4FFZ", - "Z5nVXphY3fJZJJB6VWSANIkp9Bo2R5tB5JUMtaMJmckRpI+Lik/QMjPJp/yDB/hhj29mP9foqDBsptGG", - "JE9GI/oXaXSAHrTIskRF3tvwm1fD7cGZ4LjQRd2n+WsDSz7l/xnWoQyr48Jw38/L3s5m8pM2E7KJWnr0", - "KdtGT2+RyvDX48NQW8Px6Hzcmbu/8sSpLAGWglTCny8sI9KEQvbp9vqqJQ0z8uu9vpDz5m49nL9GObA6", - "BZ/qwXr8vx87eBr55G134OIBGJUTy9HmWaYN1aSH/ugqHqTG/zqWGYA0c6ye5UcHncxM3r6UmFMlcNz3", - "npL2mCYvcUXBD1NhHqTe4IsdFeIlaMiNhKXIE/cbyftFET+tvHfn3XJZZMBWZO8jYJsYkO2OGsNdd2O1", - "IDFhgO3OB91l9+68Og2Adf/XsvhlpLWco0K0BzVO8A4JmIwuhq+31pmyk4f3MUQPlqllfZ0LoUqIElFT", - "kBTtAU9GF7yJoXd0rfzaHlk9ZXh07SzvD0I4Gw23S5EkLjY6X8VlM4LPYKnVSvYAxUYbeXgjywz4/kxt", - "jpo9EejvipVwVJS0xHU2+pmwWq69B2Cfdf09Cvptd+HSgb9KTlW5wu4KmVRxoyKgdLoYGB31/bhCupwG", - "hZ7jJlZRXL23SgLTSxr2h/q2yv4IznNiCddvFNXGXaaxo9+Mh9uxz0F3Rd/sUnTwUUDhKnwW2H8UaEn5", - "m3AQ+1GCw/onc3sqyOaHjbK8P7mLL7o3b6IAXdi51jdEpjDSxkDkkoJ+J7kE6c+6lSYFGhZaFnTYm2Md", - "b6emXXTQ8j0HUxwUvtbPK/h/rZNVUzpk4rpSbh8ZP62KFyd2V/01hS0VJLWYrMAxUWkhHadTQNdJ2O/d", - "Ji1ffFoY8d/q8qhKuGzE5V+vhSlobySwhoRkQOoop9A8Ll7tvt3tzaf++N729Z7y6AW4Ko3cJNVFbDoc", - "VhcdujoNJECWimwgFCn8PwEAAP//WUiKvIcUAAA=", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "tFhdb9u4Ev0rLG+B+3D9nQZt/Jbb7RYusEnQZNGHOg+0OLbYSEOVpOwIhv77YkjZsiPJbTZtXmKJnOGZ", + "M8MzpLY80mmmEdBZPt3yTBiRggPjn26dUbia4Y1wMT1LsJFRmVMa+ZRfMuvHWSZczPaWvMcVDdNb3uMo", + "UuBTbh0NGPieKwOST53JocdtFEMqyLUrsmqawhUvy3I36IGc3zphnP2iXHyVpwswTTR3sbIsmDBak1lv", + "wjbKxUwwDGa93UJ68Q0ix8sev8TirshgzKfb+mnSEm41wgxkBiwxxgQWjBwO5jjHgCDWeSLZAphAptCB", + "WYoItuUcaa33uXU6DbTeeSBbvtQmFY5PeeQHa4gVFz3+2NciU/1IS1gB9uHRGdF3YmWDueZTvhCGE2d/", + "ELZIOJA3RmdgXOGzGn4r8BYIGxpsRvi3BeYoCNSbVw0cZY/rxLsdB9PdSrtkdk2ftE8/XnvmWG5BMqeZ", + "1AGFQMlcLNwJJGc/g4QIrOf0DQi7D/cqcMEUWgdCvjrw/eZXw34ejvJwt3zdJ20Pj9+31PIHzNMZXi++", + "zfDSGOGTrxyktlkFa5HQP8A8Jf9LZSxBthBplAfO9zuyZbnqhfBLlT3+ERCMiq7DhHpX1xZXeZKIRQI3", + "R1iOkWlPboDXTHw1eIly58vX9P53Ry3WXG67B5/n9EmG9r/b/bWl6zp3YEgHSNguUWOR6tzOEIPAHdOi", + "Ol4fhkSCswLTwKZkc30qx5Xu08t+JdJ+5c9AT3IP53oPN8za/oAHP6tXwW1GXfoay41yxS2pdYhCRBFY", + "23f6AZCeFyAMmD930vjpy10/6CQLM5mfOZgjr/oELRGM6n0XO5eFVqJwqVtaBljHImHBsqU2bC2M0rll", + "ytrcv8pRMr0Gw5xKYcBuEhAWmJCSCeZ2tmQ6R2oEi3zFluoRZIDllKPSCavcgll7aGswNqw+HowGo1DS", + "gCJTfMrPBqPBmPd86/S0DAFtbqAPazCFixWu+sr2DSzBAEahmlfgOrohoMy0QsfgUVlnmdVemFjd8lkk", + "kHpVZIA0iSn0GjZHm0HklQy1owmZyRGkj4uKT9AyM8mn/IMH+GGPb2Y/1+ioMGym0YYkT0Yj+hdpdIAe", + "tMiyREXe2/CbV8PtwZnguNBF3af5awNLPuX/GdahDKvjwnDfz8vezmbykzYTsolaevQp20ZPb5HK8Nfj", + "w1Bbw/HofNyZu7/yxKksAZaCVMKfLywj0oRC9un2+qolDTPy672+kPPmbj2cv0Y5sDoFn+rBevy/Hzt4", + "GvnkbXfg4gEYlRPL0eZZpg3VpIf+6CoepMb/OpYZgDRzrJ7lRwedzEzevpSYUyVw3PeekvaYJi9xRcEP", + "U2EepN7gix0V4iVoyI2EpcgT9xvJ+0URP628d+fdcllkwFZk7yNgmxiQ7Y4aw113Y7UgMWGA7c4H3WX3", + "7rw6DYB1/9ey+GWktZyjQrQHNU7wDgmYjC6Gr7fWmbKTh/cxRA+WqWV9nQuhSogSUVOQFO0BT0YXvImh", + "d3St/NoeWT1leHTtLO8PQjgbDbdLkSQuNjpfxWUzgs9gqdVK9gDFRht5eCPLDPj+TG2Omj0R6O+KlXBU", + "lLTEdTb6mbBarr0HYJ91/T0K+m134dKBv0pOVbnC7gqZVHGjIqB0uhgYHfX9uEK6nAaFnuMmVlFcvbdK", + "AtNLGvaH+rbK/gjOc2IJ128U1cZdprGj34yH27HPQXdF3+xSdPBRQOEqfBbYfxRoSfmbcBD7UYLD+idz", + "eyrI5oeNsrw/uYsvujdvogBd2LnWN0SmMNLGQOSSgn4nuQTpz7qVJgUaFloWdNibYx1vp6ZddNDyPQdT", + "HBS+1s8r+H+tk1VTOmTiulJuHxk/rYoXJ3ZX/TWFLRUktZiswDFRaSEdp1NA10nY790mLV98Whjx3+ry", + "qEq4bMTlX6+FKWhvJLCGhGRA6iin0DwuXu2+3e3Np/743vb1nvLoBbgqjdwk1UVsOhxWFx26Og0kQJaK", + "bCAUKfw/AQAA//8=", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1755,7 +1757,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1773,12 +1775,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1804,3 +1806,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index cbf2515358..f54a6191ed 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1858,47 +1858,49 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1906,7 +1908,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1924,12 +1926,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1955,3 +1957,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 12172f8336..f3d5f6eaf9 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1537,47 +1537,49 @@ func (sh *strictHandler) UnionExample(ctx echo.Context) error { return nil } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1585,7 +1587,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1603,12 +1605,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1634,3 +1636,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/fiber/server.gen.go b/internal/test/strict-server/fiber/server.gen.go index 9b887e72ae..aa69ce929a 100644 --- a/internal/test/strict-server/fiber/server.gen.go +++ b/internal/test/strict-server/fiber/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "errors" @@ -1638,47 +1638,49 @@ func (sh *strictHandler) UnionExample(ctx *fiber.Ctx) error { return nil } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1686,7 +1688,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1704,12 +1706,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1735,3 +1737,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 076105a01a..b5294a5b54 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1673,47 +1673,49 @@ func (sh *strictHandler) UnionExample(ctx *gin.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1721,7 +1723,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1739,12 +1741,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1770,3 +1772,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/gorilla/server.gen.go b/internal/test/strict-server/gorilla/server.gen.go index c7ee8ecea4..e8d9dc439d 100644 --- a/internal/test/strict-server/gorilla/server.gen.go +++ b/internal/test/strict-server/gorilla/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1763,47 +1763,49 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1811,7 +1813,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1829,12 +1831,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1860,3 +1862,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/iris/server.gen.go b/internal/test/strict-server/iris/server.gen.go index 649d39e2e2..54c401bab9 100644 --- a/internal/test/strict-server/iris/server.gen.go +++ b/internal/test/strict-server/iris/server.gen.go @@ -5,7 +5,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "errors" @@ -1530,47 +1530,49 @@ func (sh *strictHandler) UnionExample(ctx iris.Context) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1578,7 +1580,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1596,12 +1598,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1627,3 +1629,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/internal/test/strict-server/stdhttp/server.gen.go b/internal/test/strict-server/stdhttp/server.gen.go index b3c693a5ba..f3073a462b 100644 --- a/internal/test/strict-server/stdhttp/server.gen.go +++ b/internal/test/strict-server/stdhttp/server.gen.go @@ -7,7 +7,7 @@ package api import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" @@ -1757,47 +1757,49 @@ func (sh *strictHandler) UnionExample(w http.ResponseWriter, r *http.Request) { } } -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - - "H4sIAAAAAAAC/+xZ23LbNhN+lR38/0Wbkqbi+Ep3TSaTtmmTjmxfdXwBESsJCQkgwFKyRqOZPkSfsE/S", - "AQHqSNtSqoMn0zuJ3BP3211+S8xYrkujFSpyrDtjFp3RymH9p8+FxS8VOvL/BLrcSkNSK9Zlr7noxXvz", - "hFmsHO8X2Kh7+VwrQlWrcmMKmXOvmn1yXn/GXD7Ckvtf/7c4YF32v2wZShbuugzveWkKZPP5PNmI4ON7", - "lrARcoG2jjb8fBme4kslLQrWJVthsuKLpgZZlzmyUg2ZNxrULndSk4pwiNZH41VjkF6gibM7Y8Zqg5Zk", - "yOGYFxW2e45XdP8T5hSeUKqB3s71G62IS+VAyMEALSqCmFzwNhy4yhhtCQX0p+A95AQO7RgtSxhJ8oGx", - "69XrEAN2LGFjtC44ennRueh4PLVBxY1kXfaqvpQww2lUP9ACQKPb6uKX648fQDrgFemSk8x5UUyh5NaN", - "eIECpCLtQ6xyches9mTrwvhZRO23MZUJi8X3WovpMQqqrtuVcr/sdE5Ut/OEXQVnbTYWQWUrDVibGfCq", - "aMn5rfqs9EQBWqttfLKsrAqShltaxWo92781IrukfGEvG2hbpoITP1LWD+Xp3IlPLRac/Dh5EoBekNwP", - "hxXzR0Xh3/g5KwZxHrfOqeuRnjgY6QmQBoG8gImkETSKGwNWKuDgpBoWCE1QSSuYBcbX4o9K9OKz3Hgb", - "R59nyZqV+3QymaR1A1W2QJVr8XUQJkyWfIiZUcN1dW+bE+uy/pR8yW6/4A7UyAkjvKfMFFxuJGbT5YlG", - "+n+ZPlhjh3ZVOo0QpSuErr1xPyxk4bvLztX30BgODaxrOV4AVwJUVRSeli5lonn4+8+/AO/R5tKhAxpx", - "gko5pIUAtwi6lORJ1cDqEmi0NLPV+x/0mxDTTzH8rTq8ansSiFrrRLaJOuZiHYjmZsNRt2uhyUCr+nbH", - "BAQa6pv6nkj7cUK1IxAHHHgpT/Ua3QSchlI6PyfDTTfSVSGAFxM+dWFCb3O+XlT33K8ejUcnfskG0/+2", - "ieACWt/b54H2Bu/pSWj3GD37wnfqqbY/RPVWJtKhTj/jdKKtSA23vERC67KZj3PubQ2xxeTvC0nIuYI+", - "guIlCuADQgvvNESTrgWf4Pedfh9ElqbqlW/xp/vHjPnk1WsgS5h3wLohf8ke6/bdcaFqshk+RqRrrh4q", - "+CjSpM7iwHlK2IZxS/6Cp96KxHmW1sdrc+vzzCmK2iP58OrjR8Iu684Bqd9znwJVuPhwzqLWLmn7Sia5", - "QxbHUqDOSnO1p+WzJdUZzOVAolhwzBDbQyPhjVa5RVpfAf3LUGmChTHoT2tKGDJQvx8nCGXlCAx3DiTV", - "U6SQ4Wud2OaMt8vIIg28WY7Tx1B9cSRMX5wL0avOy/1VXh25btZWuQf6sffr2yCz7zfLg+2Me268h/N7", - "pnb2O97TO2Lcwpbv9Bzl2DMiJcAiVVahgLHkzYford6MBpawtnGhuF8t2FBzALEPIUoetXXJHj2EuPuG", - "P5Gf72gnOfECfqquqZR87ODm1t+GyOg331RSq2d6LMMLQqs4yTH+cJjvedtWtMKPg7rvN9BLdvRw9/yO", - "L49ddfOEhZPGMDArW/ipRmS6WRZOKC/chA+HaC+kzriRPkv/BAAA///qGF+njh4AAA==", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode + "7Fnbcts2E36VHfz/RZuSpuL4SndNJpO2aZOObF91fAERKwkJCSDAUrJGo5k+RJ+wT9IBAepI21KqgyfT", + "O4ncE/fbXX5LzFiuS6MVKnKsO2MWndHKYf2nz4XFLxU68v8EutxKQ1Ir1mWvuejFe/OEWawc7xfYqHv5", + "XCtCVatyYwqZc6+afXJef8ZcPsKS+1//tzhgXfa/bBlKFu66DO95aQpk8/k82Yjg43uWsBFygbaONvx8", + "GZ7iSyUtCtYlW2Gy4oumBlmXObJSDZk3GtQud1KTinCI1kfjVWOQXqCJsztjxmqDlmTI4ZgXFbZ7jld0", + "/xPmFJ5QqoHezvUbrYhL5UDIwQAtKoKYXPA2HLjKGG0JBfSn4D3kBA7tGC1LGEnygbHr1esQA3YsYWO0", + "Ljh6edG56Hg8tUHFjWRd9qq+lDDDaVQ/0AJAo9vq4pfrjx9AOuAV6ZKTzHlRTKHk1o14gQKkIu1DrHJy", + "F6z2ZOvC+FlE7bcxlQmLxfdai+kxCqqu25Vyv+x0TlS384RdBWdtNhZBZSsNWJsZ8Kpoyfmt+qz0RAFa", + "q218sqysCpKGW1rFaj3bvzUiu6R8YS8baFumghM/UtYP5enciU8tFpz8OHkSgF6Q3A+HFfNHReHf+Dkr", + "BnEet86p65GeOBjpCZAGgbyAiaQRNIobA1Yq4OCkGhYITVBJK5gFxtfij0r04rPceBtHn2fJmpX7dDKZ", + "pHUDVbZAlWvxdRAmTJZ8iJlRw3V1b5sT67L+lHzJbr/gDtTICSO8p8wUXG4kZtPliUb6f5k+WGOHdlU6", + "jRClK4SuvXE/LGThu8vO1ffQGA4NrGs5XgBXAlRVFJ6WLmWiefj7z78A79Hm0qEDGnGCSjmkhQC3CLqU", + "5EnVwOoSaLQ0s9X7H/SbENNPMfytOrxqexKIWutEtok65mIdiOZmw1G3a6HJQKv6dscEBBrqm/qeSPtx", + "QrUjEAcceClP9RrdBJyGUjo/J8NNN9JVIYAXEz51YUJvc75eVPfcrx6NRyd+yQbT/7aJ4AJa39vngfYG", + "7+lJaPcYPfvCd+qptj9E9VYm0qFOP+N0oq1IDbe8RELrspmPc+5tDbHF5O8LSci5gj6C4iUK4ANCC+80", + "RJOuBZ/g951+H0SWpuqVb/Gn+8eM+eTVayBLmHfAuiF/yR7r9t1xoWqyGT5GpGuuHir4KNKkzuLAeUrY", + "hnFL/oKn3orEeZbWx2tz6/PMKYraI/nw6uNHwi7rzgGp33OfAlW4+HDOotYuaftKJrlDFsdSoM5Kc7Wn", + "5bMl1RnM5UCiWHDMENtDI+GNVrlFWl8B/ctQaYKFMehPa0oYMlC/HycIZeUIDHcOJNVTpJDha53Y5oy3", + "y8giDbxZjtPHUH1xJExfnAvRq87L/VVeHblu1la5B/qx9+vbILPvN8uD7Yx7bryH83umdvY73tM7YtzC", + "lu/0HOXYMyIlwCJVVqGAseTNh+it3owGlrC2caG4Xy3YUHMAsQ8hSh61dckePYS4+4Y/kZ/vaCc58QJ+", + "qq6plHzs4ObW34bI6DffVFKrZ3oswwtCqzjJMf5wmO9521a0wo+Duu830Et29HD3/I4vj11184SFk8Yw", + "MCtb+KlGZLpZFk4oL9yED4doL6TOuJE+S/8EAAD//w==", +} + +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -1805,7 +1807,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -1823,12 +1825,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -1854,3 +1856,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +} diff --git a/pkg/codegen/inline.go b/pkg/codegen/inline.go index 459255c05f..c07e1fe659 100644 --- a/pkg/codegen/inline.go +++ b/pkg/codegen/inline.go @@ -15,7 +15,7 @@ package codegen import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "fmt" @@ -35,20 +35,21 @@ func GenerateInlinedSpec(t *template.Template, importMapping importMap, swagger return "", fmt.Errorf("error marshaling swagger: %w", err) } - // gzip + // flate var buf bytes.Buffer - zw, err := gzip.NewWriterLevel(&buf, gzip.BestCompression) + zw, err := flate.NewWriter(&buf, flate.BestCompression) if err != nil { - return "", fmt.Errorf("error creating gzip compressor: %w", err) + return "", fmt.Errorf("new flate writer: %w", err) } - _, err = zw.Write(encoded) - if err != nil { - return "", fmt.Errorf("error gzipping swagger file: %w", err) + + if _, err := zw.Write(encoded); err != nil { + return "", fmt.Errorf("write flate: %w", err) } - err = zw.Close() - if err != nil { - return "", fmt.Errorf("error gzipping swagger file: %w", err) + + if err := zw.Close(); err != nil { + return "", fmt.Errorf("close flate writer: %w", err) } + str := base64.StdEncoding.EncodeToString(buf.Bytes()) var parts []string diff --git a/pkg/codegen/templates/imports.tmpl b/pkg/codegen/templates/imports.tmpl index 4c6260006b..d57c2d1cd4 100644 --- a/pkg/codegen/templates/imports.tmpl +++ b/pkg/codegen/templates/imports.tmpl @@ -8,7 +8,7 @@ package {{.PackageName}} import ( "bytes" - "compress/gzip" + "compress/flate" "context" "encoding/base64" "encoding/json" diff --git a/pkg/codegen/templates/inline.tmpl b/pkg/codegen/templates/inline.tmpl index de00120502..b76ec33365 100644 --- a/pkg/codegen/templates/inline.tmpl +++ b/pkg/codegen/templates/inline.tmpl @@ -1,24 +1,26 @@ -// Base64 encoded, gzipped, json marshaled Swagger object +// Base64 encoded, compressed with deflate, json marshaled OpenAPI spec. +// Stored as a slice of fixed-width chunks rather than one concatenated +// const string: with thousands of chunks the chained `+` fold is several +// times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ -{{range .SpecParts}} - "{{.}}",{{end}} -} +{{range .SpecParts}} "{{.}}", +{{end}}} -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode +// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, +// after base64-decoding and flate-decompressing the embedded blob. func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + encoded := strings.Join(swaggerSpec, "") + compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("error base64 decoding spec: %w", err) } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } + zr := flate.NewReader(bytes.NewReader(compressed)) var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) + if _, err := buf.ReadFrom(zr); err != nil { + return nil, fmt.Errorf("read flate: %w", err) + } + if err := zr.Close(); err != nil { + return nil, fmt.Errorf("close flate reader: %w", err) } return buf.Bytes(), nil @@ -26,7 +28,7 @@ func decodeSpec() ([]byte, error) { var rawSpec = decodeSpecCached() -// a naive cached of a decoded swagger spec +// a naive cache of the decoded OpenAPI spec func decodeSpecCached() func() ([]byte, error) { data, err := decodeSpec() return func() ([]byte, error) { @@ -51,12 +53,12 @@ func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { return res } -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { +// GetSpec returns the OpenAPI specification corresponding to the generated +// code in this file. External references in the spec are resolved through +// PathToRawSpec; externally-referenced files must be embedded in their +// corresponding Go packages (via the import-mapping feature). URL-based +// external refs are not supported. +func GetSpec() (swagger *openapi3.T, err error) { resolvePath := PathToRawSpec("") loader := openapi3.NewLoader() @@ -82,3 +84,22 @@ func GetSwagger() (swagger *openapi3.T, err error) { } return } + +// GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI +// specification: decompressed but not unmarshaled. External references +// are not resolved here; the bytes are the spec exactly as embedded by +// codegen. The result is cached at package init time, so repeated calls +// are cheap. +func GetSpecJSON() ([]byte, error) { + return rawSpec() +} + +// GetSwagger returns the OpenAPI specification corresponding to the +// generated code in this file. +// +// Deprecated: GetSwagger predates kin-openapi renaming openapi3.Swagger +// to openapi3.T. Use [GetSpec] instead. This wrapper is retained for +// backwards compatibility. +func GetSwagger() (*openapi3.T, error) { + return GetSpec() +}