oq

package
v1.21.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 11 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 (new jq-style)
openapi spec query 'schemas.components | sort_by(depth; desc) | first(10) | pick name, depth' petstore.yaml

# Dead components (unreferenced)
openapi spec query 'schemas.components | select(in_degree == 0) | pick 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)
schemas.components Component schemas only
schemas.inline Inline schemas only
operations All operations
Traversal Stages
Stage Description
refs-out Direct outgoing references (with edge annotations)
refs-in Direct incoming references (with edge annotations)
reachable Transitive closure of outgoing refs
ancestors Transitive closure of incoming refs
properties Property sub-schemas (with edge annotations)
union-members allOf/oneOf/anyOf children (with edge annotations)
items Array items schema (with edge annotations)
ops Schemas → operations
schemas Operations → schemas
path(A; B) Shortest path between two schemas
connected Full connected component (schemas + operations)
blast-radius Ancestors + all affected operations
neighbors(N) Bidirectional neighborhood within N hops
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
tag-boundary Schemas used by operations across multiple tags
shared-refs Schemas shared by ALL operations in result set
Filter & Transform Stages
Stage Description
select(expr) Filter by predicate (jq-style)
pick f1, f2 Project fields
sort_by(field) / sort_by(field; desc) Sort (ascending by default)
first(N) Limit to first N results
last(N) Limit to last N results
sample(N) Deterministic random sample
top(N; field) Sort desc + take
bottom(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

Legacy syntax (where, sort, take, head, select fields, group-by, count) is still supported.

Meta Stages
Stage Description
explain Print query plan
fields List available fields
format(fmt) Set output format (table/json/markdown/toon)
Function Definitions & Modules

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

# Inline definitions
def hot: select(in_degree > 10);
def impact($name): select(name == $name) | blast-radius;
schemas.components | hot | pick name, in_degree

# Load from file
include "stdlib.oq";
schemas.components | hot | pick name, in_degree

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
in_degree int Incoming reference count
out_degree int Outgoing reference count
union_width int Union member count
property_count int Property count
is_component bool In components/schemas
is_inline bool Defined inline
is_circular bool Part of circular reference
has_ref bool Has $ref
hash string Content hash
path string JSON pointer
op_count int Operations using this schema
tag_count int Distinct tags across operations
Operation Fields
Field Type Description
name string operationId or METHOD /path
method string HTTP method
path string URL path
operation_id string operationId
schema_count int Reachable schema count
component_count int Reachable component count
tag string First tag
parameter_count int Parameter count
deprecated bool Deprecated flag
description string Description
summary string Summary
Edge Annotation Fields

Available on rows produced by 1-hop traversal stages (refs-out, refs-in, properties, union-members, items):

Field Type Description
edge_kind string Edge type: property, items, allOf, oneOf, ref, ...
edge_label string Edge label: property name, array index, etc.
edge_from string Source node name

Expressions

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

depth > 5
type == "object"
name matches "Error.*"
property_count > 3 and not is_component
has(oneOf) and not has(discriminator)
(depth > 10 or union_width > 5) and is_component
name // "unnamed"                              # alternative: fallback if null/falsy
if is_component then depth > 3 else true end   # conditional
"prefix_\(name)"                               # string interpolation
Operators
Operator Description
==, !=, >, <, >=, <= Comparison
and, or, not Logical
// 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 | select(name == "Pet") | let $pet = name | reachable | select(name != $pet)

Output Formats

Use --format flag or inline format stage:

openapi spec query 'schemas | count' spec.yaml --format json
openapi spec query 'schemas | first(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 | select(union_width > 0) | sort_by(union_width; desc) | first(10)

# Central schemas (most referenced)
schemas.components | sort_by(in_degree; desc) | first(10) | pick name, in_degree

# Operation sprawl
operations | sort_by(schema_count; desc) | first(10) | pick name, schema_count

# Circular references
schemas | select(is_circular) | pick name, path

# Shortest path between schemas
schemas | path(Pet; Address) | pick name

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

# Explain query plan
schemas.components | select(depth > 5) | sort_by(depth; desc) | explain

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

# Group by type
schemas | group_by(type)

# Edge annotations — how does Pet reference other schemas?
schemas.components | select(name == "Pet") | refs-out | pick name, edge_kind, edge_label, edge_from

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

# 2-hop neighborhood
schemas.components | select(name == "Pet") | neighbors(2) | pick name

# Orphaned schemas
schemas.components | orphans | pick name

# Leaf nodes
schemas.components | leaves | pick name, in_degree

# Detect cycles
schemas | cycles

# Discover clusters
schemas.components | clusters

# Cross-tag schemas
schemas | tag-boundary | pick name, tag_count

# Schemas shared across all operations
operations | shared-refs | pick name, op_count

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

# User-defined functions
def hot: select(in_degree > 10);
def impact($name): select(name == $name) | blast-radius;
schemas.components | hot | pick name, in_degree

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

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 with jq-inspired syntax:

schemas.components | select(depth > 5) | sort_by(depth; desc) | first(10) | pick name, depth

Legacy syntax (where, sort, take, select fields) is also supported.

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

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)
}

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
)

type Row

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

	// Edge annotations (populated by 1-hop traversal stages)
	EdgeKind  string // edge type: "property", "items", "allOf", "oneOf", "ref", etc.
	EdgeLabel string // edge label: property name, array index, etc.
	EdgeFrom  string // source node name
}

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, StageTop, StageBottom
	PathFrom  string   // for StagePath
	PathTo    string   // for StagePath
	Format    string   // for StageFormat
	VarName   string   // for StageLet
}

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 (backward compat).

type StageKind

type StageKind int

StageKind represents the type of pipeline stage.

const (
	StageSource StageKind = iota
	StageWhere
	StageSelect
	StageSort
	StageTake
	StageUnique
	StageGroupBy
	StageCount
	StageRefsOut
	StageRefsIn
	StageReachable
	StageAncestors
	StageProperties
	StageUnionMembers
	StageItems
	StageOps
	StageSchemas
	StageExplain
	StageFields
	StageSample
	StagePath
	StageTop
	StageBottom
	StageFormat
	StageConnected
	StageBlastRadius
	StageNeighbors
	StageOrphans
	StageLeaves
	StageCycles
	StageClusters
	StageTagBoundary
	StageSharedRefs
	StageLast
	StageLet
)

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