fixer

package
v1.20.3 Latest Latest
Warning

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

Go to latest
Published: Dec 9, 2025 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package fixer provides automatic fixes for common OpenAPI Specification validation errors.

The fixer analyzes OAS documents and applies fixes for issues that would cause validation failures. It supports both OAS 2.0 and OAS 3.x documents. The fixer preserves the input file format (JSON or YAML) in the FixResult.SourceFormat field, allowing tools to maintain format consistency when writing output.

Quick Start

Fix a file using functional options:

result, err := fixer.FixWithOptions(
	fixer.WithFilePath("openapi.yaml"),
)
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Applied %d fixes\n", result.FixCount)

Or use a reusable Fixer instance:

f := fixer.New()
f.InferTypes = true // Infer parameter types from naming conventions
result1, _ := f.Fix("api1.yaml")
result2, _ := f.Fix("api2.yaml")

Supported Fixes

The fixer currently supports the following automatic fixes:

  • Missing path parameters: Adds Parameter objects for path template variables that are not declared in the operation's parameters list. For example, if a path is "/users/{userId}" but the operation doesn't declare a "userId" path parameter, the fixer adds one with type "string" (or inferred type if enabled).

Type Inference

When InferTypes is enabled (--infer flag in CLI), the fixer uses naming conventions to determine parameter types:

  • Names ending in "id", "Id", or "ID" -> integer
  • Names containing "uuid" or "guid" -> string with format "uuid"
  • All other names -> string

Pipeline Usage

The fixer is designed to work in a pipeline with other oastools commands:

# Fix and validate
oastools fix api.yaml | oastools validate -q -

# Fix and save
oastools fix api.yaml -o fixed.yaml

The fixer integrates with other oastools packages:

Example

Example demonstrates basic usage of the fixer package.

package main

import (
	"fmt"
	"log"

	"github.com/erraggy/oastools/fixer"
	"github.com/erraggy/oastools/parser"
)

func main() {
	// Parse a spec with missing path parameters
	spec := `
openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
paths:
  /users/{userId}:
    get:
      operationId: getUser
      responses:
        '200':
          description: Success
`
	p := parser.New()
	parseResult, err := p.ParseBytes([]byte(spec))
	if err != nil {
		log.Fatal(err)
	}

	// Fix the specification
	f := fixer.New()
	result, err := f.FixParsed(*parseResult)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Applied %d fix(es)\n", result.FixCount)
	for _, fix := range result.Fixes {
		fmt.Printf("  %s: %s\n", fix.Type, fix.Description)
	}

}
Output:

Applied 1 fix(es)
  missing-path-parameter: Added missing path parameter 'userId' (type: string)
Example (Swagger20)

Example_swagger20 demonstrates fixing an OAS 2.0 (Swagger) specification.

package main

import (
	"fmt"
	"log"

	"github.com/erraggy/oastools/fixer"
	"github.com/erraggy/oastools/parser"
)

func main() {
	spec := `
swagger: "2.0"
info:
  title: Test API
  version: 1.0.0
paths:
  /pets/{petId}:
    get:
      operationId: getPet
      responses:
        '200':
          description: Success
`
	p := parser.New()
	parseResult, err := p.ParseBytes([]byte(spec))
	if err != nil {
		log.Fatal(err)
	}

	f := fixer.New()
	result, err := f.FixParsed(*parseResult)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("OAS Version: %s\n", result.SourceVersion)
	fmt.Printf("Fixes: %d\n", result.FixCount)

}
Output:

OAS Version: 2.0
Fixes: 1

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Fix

type Fix struct {
	// Type identifies the category of fix
	Type FixType
	// Path is the JSON path to the fixed location (e.g., "paths./users/{id}.get.parameters")
	Path string
	// Description is a human-readable description of the fix
	Description string
	// Before is the state before the fix (nil if adding new element)
	Before any
	// After is the value that was added or changed
	After any
}

Fix represents a single fix applied to the document

type FixResult

type FixResult struct {
	// Document contains the fixed document (*parser.OAS2Document or *parser.OAS3Document)
	Document any
	// SourceVersion is the detected source OAS version string
	SourceVersion string
	// SourceOASVersion is the enumerated source OAS version
	SourceOASVersion parser.OASVersion
	// SourceFormat is the format of the source file (JSON or YAML)
	SourceFormat parser.SourceFormat
	// SourcePath is the path to the source file
	SourcePath string
	// Fixes contains all fixes applied
	Fixes []Fix
	// FixCount is the total number of fixes applied
	FixCount int
	// Success is true if fixing completed without errors
	Success bool
	// Stats contains statistical information about the document
	Stats parser.DocumentStats
}

FixResult contains the results of a fix operation

func FixWithOptions

func FixWithOptions(opts ...Option) (*FixResult, error)

FixWithOptions fixes an OpenAPI specification using functional options. This provides a flexible, extensible API that combines input source selection and configuration in a single function call.

Example:

result, err := fixer.FixWithOptions(
    fixer.WithFilePath("openapi.yaml"),
    fixer.WithInferTypes(true),
)
Example

ExampleFixWithOptions demonstrates using functional options.

package main

import (
	"fmt"
	"log"

	"github.com/erraggy/oastools/fixer"
	"github.com/erraggy/oastools/parser"
)

func main() {
	spec := `
openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
paths:
  /projects/{projectId}:
    get:
      operationId: getProject
      responses:
        '200':
          description: Success
`
	p := parser.New()
	parseResult, err := p.ParseBytes([]byte(spec))
	if err != nil {
		log.Fatal(err)
	}

	// Fix using functional options with type inference
	result, err := fixer.FixWithOptions(
		fixer.WithParsed(*parseResult),
		fixer.WithInferTypes(true),
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Applied %d fix(es)\n", result.FixCount)
	for _, fix := range result.Fixes {
		fmt.Printf("  %s: %s\n", fix.Type, fix.Description)
	}

}
Output:

Applied 1 fix(es)
  missing-path-parameter: Added missing path parameter 'projectId' (type: integer)

func (*FixResult) HasFixes

func (r *FixResult) HasFixes() bool

HasFixes returns true if any fixes were applied

Example

ExampleFixResult_HasFixes demonstrates checking if fixes were applied.

package main

import (
	"fmt"
	"log"

	"github.com/erraggy/oastools/fixer"
	"github.com/erraggy/oastools/parser"
)

func main() {
	// A spec with no issues needs no fixes
	spec := `
openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
paths:
  /users/{userId}:
    get:
      operationId: getUser
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Success
`
	p := parser.New()
	parseResult, err := p.ParseBytes([]byte(spec))
	if err != nil {
		log.Fatal(err)
	}

	f := fixer.New()
	result, err := f.FixParsed(*parseResult)
	if err != nil {
		log.Fatal(err)
	}

	if result.HasFixes() {
		fmt.Printf("Applied %d fixes\n", result.FixCount)
	} else {
		fmt.Println("No fixes needed")
	}

}
Output:

No fixes needed

type FixType

type FixType string

FixType identifies the type of fix applied

const (
	// FixTypeMissingPathParameter indicates a missing path parameter was added
	FixTypeMissingPathParameter FixType = "missing-path-parameter"
)

type Fixer

type Fixer struct {
	// InferTypes enables type inference for path parameters based on naming conventions.
	// When true, parameter names ending in "id"/"Id"/"ID" become integer type,
	// names containing "uuid"/"guid" become string with format uuid,
	// and all others become string type.
	InferTypes bool
	// EnabledFixes specifies which fix types to apply.
	// If nil or empty, all fix types are enabled.
	EnabledFixes []FixType
	// UserAgent is the User-Agent string used when fetching URLs.
	// Defaults to "oastools" if not set.
	UserAgent string
}

Fixer handles automatic fixing of OAS validation issues

func New

func New() *Fixer

New creates a new Fixer instance with default settings

func (*Fixer) Fix

func (f *Fixer) Fix(specPath string) (*FixResult, error)

Fix fixes an OpenAPI specification file and returns the result

func (*Fixer) FixParsed

func (f *Fixer) FixParsed(parseResult parser.ParseResult) (*FixResult, error)

FixParsed fixes an already-parsed OpenAPI specification. The fixer operates on the parsed document structure and does not require a valid specification - it will attempt to fix issues even if validation errors exist (since that's often the reason for using the fixer).

type Option

type Option func(*fixConfig) error

Option is a function that configures a fix operation

func WithEnabledFixes

func WithEnabledFixes(fixes ...FixType) Option

WithEnabledFixes specifies which fix types to apply

func WithFilePath

func WithFilePath(path string) Option

WithFilePath specifies the file path (local file or URL) to fix

func WithInferTypes

func WithInferTypes(infer bool) Option

WithInferTypes enables type inference for path parameters

func WithParsed

func WithParsed(result parser.ParseResult) Option

WithParsed specifies an already-parsed specification to fix

func WithUserAgent

func WithUserAgent(userAgent string) Option

WithUserAgent sets the User-Agent string for HTTP requests

Jump to

Keyboard shortcuts

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