oq

package
v1.22.0 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 15 Imported by: 0

README

oq — OpenAPI Query Language

oq is a pipeline query language for exploring OpenAPI schema reference graphs. It lets you ask structural and semantic questions about schemas and operations at the command line.

Quick Start

# Count all schemas
openapi spec query 'schemas | count' petstore.yaml

# Top 10 deepest component schemas
openapi spec query 'schemas | where(isComponent) | sort-by(depth, desc) | take(10) | select name, depth' petstore.yaml

# Dead components (unreferenced)
openapi spec query 'schemas | where(isComponent) | where(inDegree == 0) | select name' petstore.yaml

Stdin is supported:

cat spec.yaml | openapi spec query 'schemas | count'

Pipeline Syntax

Queries are left-to-right pipelines separated by |:

source | stage | stage | ... | terminal
Sources
Source Description
schemas All schemas (component + inline)
operations All operations
components All component types (schemas, parameters, responses, headers, security-schemes). Filter with where(kind == "schema") etc.
webhooks Webhook operations only
servers Document-level servers
tags Document-level tags
security Global security requirements
Traversal Stages
Stage Description
refs Bidirectional refs: 1-hop, with direction annotation (/)
refs(*) Bidirectional transitive closure
refs(out) / refs(out, *) Outgoing refs only: 1-hop or closure
refs(in) / refs(in, *) Incoming refs only: 1-hop or closure
refs(N) / refs(out, N) Depth-limited to N hops
properties / properties(*) Property sub-schemas (allOf-flattening). properties(*) recursively expands through $ref, oneOf, anyOf with qualified from paths
members allOf/oneOf/anyOf children, or expand group rows into schemas
items Array items schema (with edge annotations)
additional-properties Expand to additionalProperties schema
pattern-properties Expand to patternProperties schemas
parent Navigate to structural parent schema (via graph in-edges)
to-operations Schemas → operations
to-schemas Operations → schemas
path(A, B) Shortest bidirectional path between two schemas (with direction annotation)
blast-radius Ancestors + all affected operations
Navigation Stages

Navigate into the internal structure of operations. These stages produce new row types (parameters, responses, etc.) that can be filtered and inspected.

Stage Description
parameters Operation parameters
responses Operation responses
request-body Operation request body
content-types Content types from response or request body
headers Response headers
callbacks Operation callbacks → callback operations
links Response links
to-schema Extract schema from parameter, content-type, or header
operation Back-navigate to source operation
security Operation security requirements
Analysis Stages
Stage Description
orphans Schemas with no incoming refs and no operation usage
leaves Schemas with no outgoing refs (terminal nodes)
cycles Strongly connected components (actual cycles)
clusters Weakly connected component grouping
cross-tag Schemas used by operations across multiple tags
shared-refs Schemas shared by ALL operations in result set
Filter & Transform Stages
Stage Description
where(expr) Filter by predicate
select f1, f2 Project fields
sort-by(field) / sort-by(field, desc) Sort (ascending by default)
take(N) Limit to first N results
last(N) Limit to last N results
sample(N) Deterministic random sample
highest(N, field) Sort desc + take
lowest(N, field) Sort asc + take
unique Deduplicate
group-by(field) Group and count
length Count rows
let $var = expr Bind expression result to a variable
Meta Stages
Stage Description
explain Print query plan
fields List available fields
format(fmt) Set output format (table/json/markdown/toon)
to-yaml Output raw YAML nodes from underlying spec objects

The to-yaml stage uses path (JSON pointer) as the wrapper key for each emitted node, giving full attribution to the source location in the spec.

Function Definitions & Modules

Define reusable functions with def and load them from .oq files with include:

# Inline definitions
def hot: where(inDegree > 10);
def impact($name): where(name == $name) | blast-radius;
schemas | where(isComponent) | hot | select name, inDegree

# Load from file
include "stdlib.oq";
schemas | where(isComponent) | hot | select name, inDegree

Def syntax: def name: body; or def name($p1, $p2): body; Module search paths: current directory, then ~/.config/oq/

Fields

Schema Fields
Field Type Description
name string Component name or JSON pointer
type string Schema type
depth int Max nesting depth
inDegree int Incoming reference count
outDegree int Outgoing reference count
unionWidth int Union member count
propertyCount int Property count
isComponent bool In components/schemas
isInline bool Defined inline
isCircular bool Part of circular reference
hasRef bool Has $ref
hash string Content hash
location string Fully qualified JSON pointer
opCount int Operations using this schema
tagCount int Distinct tags across operations
Operation Fields
Field Type Description
name string operationId or METHOD /path
method string HTTP method
path string URL path
operationId string operationId
schemaCount int Reachable schema count
componentCount int Reachable component count
tag string First tag
parameterCount int Parameter count
deprecated bool Deprecated flag
description string Description
summary string Summary
isWebhook bool Whether the operation is a webhook
callbackName string Callback name (set by callbacks stage)
callbackCount int Number of callbacks
Edge Annotation Fields

Available on rows produced by traversal stages (refs, properties, members, items, path).

Field Type Description
via string Structural edge kind: property, items, allOf, oneOf, ref, ...
key string Structural edge label: property name, array index, etc.
from string Source schema name (the schema containing the relationship)
seed string Seed schema name (the schema that initiated the traversal)
bfsDepth int BFS depth from seed
direction string (outgoing) or (incoming) — set by bidi traversals (refs, path)
Parameter Fields

Produced by the parameters navigation stage.

Field Type Description
name string Parameter name
in string Location: query, header, path, cookie
required bool Required flag
deprecated bool Deprecated flag
description string Description
style string Serialization style
explode bool Explode flag
hasSchema bool Has associated schema
allowEmptyValue bool Allow empty value
allowReserved bool Allow reserved characters
operation string Source operation name
Response Fields

Produced by the responses navigation stage.

Field Type Description
statusCode string HTTP status code
name string Alias for statusCode
description string Response description
contentTypeCount int Number of content types
headerCount int Number of headers
linkCount int Number of links
hasContent bool Has content types
operation string Source operation name
Request Body Fields

Produced by the request-body navigation stage.

Field Type Description
name string Always "request-body"
description string Request body description
required bool Required flag
contentTypeCount int Number of content types
operation string Source operation name
Content Type Fields

Produced by the content-types navigation stage.

Field Type Description
mediaType string Media type (e.g. application/json)
name string Alias for mediaType
hasSchema bool Has associated schema
hasEncoding bool Has encoding map
hasExample bool Has example or examples
statusCode string Status code (if from a response)
operation string Source operation name
Header Fields

Produced by the headers navigation stage.

Field Type Description
name string Header name
description string Header description
required bool Required flag
deprecated bool Deprecated flag
hasSchema bool Has associated schema
statusCode string Status code of parent response
operation string Source operation name
Server Fields
Field Type Description
url string Server URL
name string Server name
description string Server description
variableCount int Number of server variables
Tag Fields
Field Type Description
name string Tag name
description string Tag description
summary string Tag summary
operationCount int Number of operations with this tag
Field Type Description
name string Link name
operationId string Target operation ID
operationRef string Target operation reference
description string Link description
parameterCount int Number of link parameters
hasRequestBody bool Whether the link has a request body
hasServer bool Whether the link has a server override
statusCode string Source response status code
operation string Source operation

Expressions

oq supports a rich expression language used in where(), let, and if-then-else:

depth > 5
type == "object"
name matches "Error.*"
propertyCount > 3 and not isComponent
has(oneOf) and not has(discriminator)
(depth > 10 or unionWidth > 5) and isComponent
name // "unnamed"                              # alternative: fallback if null/falsy
name default "unnamed"                         # same as above (alias)
if isComponent then depth > 3 else true end   # conditional
"prefix_\(name)"                               # string interpolation
Operators
Operator Description
==, !=, >, <, >=, <= Comparison
and, or, not Logical
// (or default) Alternative (returns left if truthy, else right)
has(field) True if field is non-null/non-zero
matches "regex" Regex match
if cond then a else b end Conditional (elif supported)
\(expr) String interpolation inside "..."
Variables

Use let to bind values for use in later stages:

schemas | where(name == "Pet") | let $pet = name | refs(out) | where(name != $pet)

Output Formats

Use --format flag or inline format stage:

openapi spec query 'schemas | count' spec.yaml --format json
openapi spec query 'schemas | take(5) | format(markdown)' spec.yaml
Format Description
table Aligned columns (default)
json JSON array
markdown Markdown table
toon TOON tabular format

Examples

# Wide union trees
schemas | where(unionWidth > 0) | sort-by(unionWidth, desc) | take(10)

# Central schemas (most referenced)
schemas | where(isComponent) | sort-by(inDegree, desc) | take(10) | select name, inDegree

# Operation sprawl
operations | sort-by(schemaCount, desc) | take(10) | select name, schemaCount

# Circular references
schemas | where(isCircular) | select name, path

# Shortest path between schemas
schemas | path(Pet, Address) | select name

# Walk an operation to connected schemas and back to operations
operations | where(name == "GET /users") | to-schemas | to-operations | select name, method, path

# Explain query plan
schemas | where(isComponent) | where(depth > 5) | sort-by(depth, desc) | explain

# Regex filter
schemas | where(name matches "Error.*") | select name, path

# Group by type
schemas | group-by(type)

# Edge annotations — how does Pet reference other schemas?
schemas | where(isComponent) | where(name == "Pet") | refs(out) | select name, via, key, from

# Blast radius — what breaks if Error changes?
schemas | where(isComponent) | where(name == "Error") | blast-radius | length

# 1-hop bidirectional refs (with direction arrows)
schemas | where(isComponent) | where(name == "Pet") | refs | select name, direction, via, key

# Orphaned schemas
schemas | where(isComponent) | orphans | select name

# Leaf nodes
schemas | where(isComponent) | leaves | select name, inDegree

# Detect cycles
schemas | cycles

# Discover clusters
schemas | where(isComponent) | clusters

# Cross-tag schemas
schemas | cross-tag | select name, tagCount

# Schemas shared across all operations
operations | shared-refs | select name, opCount

# Variable binding — find Pet's refs(out) schemas (excluding Pet itself)
schemas | where(name == "Pet") | let $pet = name | refs(out) | where(name != $pet) | select name

# User-defined functions
def hot: where(inDegree > 10);
def impact($name): where(name == $name) | blast-radius;
schemas | where(isComponent) | hot | select name, inDegree

# Alternative operator — fallback for missing values
schemas | where(name // "unnamed" != "unnamed") | select name

# --- Navigation examples ---

# List all parameters for a specific operation
operations | where(name == "GET /pets") | parameters | select name, in, required

# Find operations with required query parameters
operations | parameters | where(in == "query" and required) | select name, operation

# Inspect responses for an operation
operations | where(name == "GET /pets") | responses | select statusCode, description

# Drill into content types of a response
operations | where(name == "GET /pets") | responses | where(statusCode == "200") | content-types | select mediaType, hasSchema

# Extract schemas from content types
operations | where(name == "GET /pets") | responses | content-types | to-schema | select name, type

# List response headers
operations | responses | where(statusCode == "200") | headers | select name, required, operation

# Navigate from parameter back to its operation
operations | parameters | where(name == "limit") | operation | select name, method, path

# Request body content types
operations | where(method == "post") | request-body | content-types | select mediaType, hasSchema, operation

# Extract raw YAML for a schema
schemas | where(name == "Pet") | to-yaml

# --- New capabilities ---

# Webhook operations
webhooks | select name, method, path

# Document servers
servers | select url, description, variableCount

# Tags with operation counts
tags | select name, operationCount | sort-by(operationCount, desc)

# Callback operations
operations | where(callbackCount > 0) | callbacks | select name, callbackName

# Response links
operations | responses | links | select name, operationId

# Additional/pattern properties
schemas | where(has(additionalProperties)) | additional-properties
schemas | where(has(patternProperties)) | pattern-properties

# Schemas with default values
schemas | properties | where(has(default)) | select from, key, default

# Extension fields (use underscores for dashes in expressions)
operations | where(has(x_speakeasy_name_override)) | select name, x_speakeasy_name_override

CLI Reference

# Run query-reference for the full language reference
openapi spec query-reference

# Inline query
openapi spec query '<query>' <spec-file>

# Query from file
openapi spec query -f query.oq <spec-file>

# With output format
openapi spec query '<query>' <spec-file> --format json

# From stdin
cat spec.yaml | openapi spec query '<query>'

Documentation

Overview

Package oq implements a pipeline query language for OpenAPI schema graphs.

Queries are written as pipeline expressions:

schemas | where(depth > 5) | sort-by(depth, desc) | take(10) | select name, depth

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExpandDefs

func ExpandDefs(pipelineText string, defs []FuncDef) (string, error)

ExpandDefs performs text-level macro expansion on pipeline segments. Each segment that matches a def name gets replaced with the def's body (with params substituted).

func FieldValuePublic

func FieldValuePublic(row Row, name string, g *graph.SchemaGraph) expr.Value

FieldValuePublic returns the value of a named field for the given row. Exported for testing and external consumers.

func FormatJSON

func FormatJSON(result *Result, g *graph.SchemaGraph) string

FormatJSON formats a result as JSON.

func FormatMarkdown

func FormatMarkdown(result *Result, g *graph.SchemaGraph) string

FormatMarkdown formats a result as a markdown table.

func FormatTable

func FormatTable(result *Result, g *graph.SchemaGraph) string

FormatTable formats a result as a simple table string.

func FormatToon

func FormatToon(result *Result, g *graph.SchemaGraph) string

FormatToon formats a result in the TOON (Token-Oriented Object Notation) format. TOON uses tabular array syntax for uniform rows: header[N]{field1,field2,...}: followed by comma-delimited data rows. See https://github.com/toon-format/toon

func FormatYAML added in v1.22.0

func FormatYAML(result *Result, g *graph.SchemaGraph) string

FormatYAML formats results as raw YAML from the underlying schema/operation objects. For multiple results, outputs a YAML stream with --- separators. This enables piping into yq for content-level queries.

Types

type FuncDef

type FuncDef struct {
	Name   string
	Params []string // with $ prefix
	Body   string   // raw pipeline text
}

FuncDef represents a user-defined function.

func LoadModule

func LoadModule(path string, searchPaths []string) ([]FuncDef, error)

LoadModule loads function definitions from a .oq module file.

type GroupResult

type GroupResult struct {
	Key   string
	Count int
	Names []string
}

GroupResult represents a group-by aggregation result.

type Query

type Query struct {
	Includes []string
	Defs     []FuncDef
	Stages   []Stage
}

Query represents a parsed query with optional includes, defs, and pipeline stages.

func ParseQuery

func ParseQuery(query string) (*Query, error)

ParseQuery parses a full query string including optional includes, defs, and pipeline.

type Result

type Result struct {
	Rows       []Row
	Fields     []string // projected fields (empty = all)
	IsCount    bool
	Count      int
	Groups     []GroupResult
	Explain    string // human-readable pipeline explanation
	FormatHint string // format preference from format stage (table, json, markdown, toon)
	EmitYAML   bool   // emit raw YAML nodes instead of formatted output
}

Result is the output of a query execution.

func Execute

func Execute(query string, g *graph.SchemaGraph) (*Result, error)

Execute parses and executes a query against the given graph.

func ExecuteWithSearchPaths

func ExecuteWithSearchPaths(query string, g *graph.SchemaGraph, searchPaths []string) (*Result, error)

ExecuteWithSearchPaths parses and executes a query, searching for modules in the given paths.

type ResultKind

type ResultKind int

ResultKind distinguishes between schema and operation result rows.

const (
	SchemaResult ResultKind = iota
	OperationResult
	GroupRowResult
	ParameterResult
	ResponseResult
	RequestBodyResult
	ContentTypeResult
	HeaderResult
	SecuritySchemeResult
	SecurityRequirementResult
	ServerResult
	TagResult
	LinkResult
)

type Row

type Row struct {
	Kind      ResultKind
	SchemaIdx int // index into SchemaGraph.Schemas
	OpIdx     int // index into SchemaGraph.Operations

	// Edge annotations (populated by traversal stages)
	Via       string // edge type: "property", "items", "allOf", "oneOf", "ref", etc.
	Key       string // edge key: property name, array index, etc.
	From      string // source node name (the node that contains the reference)
	Target    string // target/seed node name (the node traversal originated from)
	Direction string // "→" (outgoing) or "←" (incoming) — set by bidi traversals

	// BFS depth (populated by depth-limited traversals)
	BFSDepth int

	// Group annotations (populated by group-by stages)
	GroupKey   string   // group key value
	GroupCount int      // number of members in the group
	GroupNames []string // member names

	// Navigation objects (populated by navigation stages)
	Parameter      *openapi.Parameter
	Response       *openapi.Response
	RequestBody    *openapi.RequestBody
	ContentType    *openapi.MediaType
	Header         *openapi.Header
	SecurityScheme *openapi.SecurityScheme

	// Propagated context from parent navigation stages
	StatusCode    string   // propagated from response rows to content-types/headers
	MediaTypeName string   // media type key (e.g., "application/json")
	HeaderName    string   // header name
	ComponentKey  string   // component key name or parameter name
	SchemeName    string   // security scheme name
	Scopes        []string // security requirement scopes
	SourceOpIdx   int      // operation this row originated from (-1 if N/A)

	// Server, Tag, Link objects (populated by server/tag/link sources/stages)
	Server       *openapi.Server
	Tag          *openapi.Tag
	Link         *openapi.Link
	LinkName     string // link name within response
	CallbackName string // callback name within operation
}

Row represents a single result in the pipeline.

type Stage

type Stage struct {
	Kind      StageKind
	Source    string   // for StageSource
	Expr      string   // for StageWhere, StageLet
	Fields    []string // for StageSelect, StageGroupBy
	SortField string   // for StageSort
	SortDesc  bool     // for StageSort
	Limit     int      // for StageTake, StageLast, StageSample, StageHighest, StageLowest, StageRefs
	PathFrom  string   // for StagePath
	PathTo    string   // for StagePath
	Format    string   // for StageFormat
	VarName   string   // for StageLet
	RefsDir   string   // for StageRefs: "out", "in", or "" (bidi)
}

Stage represents a single stage in the query pipeline.

func Parse

func Parse(query string) ([]Stage, error)

Parse splits a pipeline query string into stages.

type StageKind

type StageKind int

StageKind represents the type of pipeline stage.

const (
	StageSource StageKind = iota
	StageWhere
	StageSelect
	StageSort
	StageTake
	StageUnique
	StageGroupBy
	StageCount
	StageRefs
	StageProperties
	StageItems
	StageToOperations
	StageToSchemas
	StageExplain
	StageFields
	StageSample
	StagePath
	StageHighest
	StageLowest
	StageFormat
	StageBlastRadius
	StageOrphans
	StageLeaves
	StageCycles
	StageClusters
	StageCrossTag
	StageSharedRefs
	StageLast
	StageLet
	StageOrigin
	StageToYAML
	StageParameters
	StageResponses
	StageRequestBody
	StageContentTypes
	StageHeaders
	StageToSchema             // singular: extract schema from nav row
	StageOperation            // back-navigate to source operation
	StageSecurity             // operation security requirements
	StageMembers              // union members (allOf/oneOf/anyOf children) or group row expansion
	StageCallbacks            // operation callbacks → operations
	StageLinks                // response links
	StageAdditionalProperties // schema additional properties traversal
	StagePatternProperties    // schema pattern properties traversal
)

Directories

Path Synopsis
Package expr provides a predicate expression parser and evaluator for the oq query language.
Package expr provides a predicate expression parser and evaluator for the oq query language.

Jump to

Keyboard shortcuts

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