Spec transforms
Transforms rewrite the OpenAPI spec before generation. They are the escape hatch for anything Studio has no first-class control for, and unlike a hook they apply to every language at once.
Reach for them when the spec is the problem and you can't fix the spec at its source.
Anatomy
A transform is a command, a JSONPath target, and a payload. Transforms live in the transforms setting, as a list run in order.
commandchoicerequiredupdate, append, merge, remove, move or copy. Each is described under commands.
reasontextWhy this transform exists. It's shown in warnings, so write it for the next person.
args.targetJSONPath or listWhat the command acts on: one JSONPath, or a list of them.
args.valueany JSONThe payload for update, append and merge.
args.from, args.toJSONPathThe source and destination for move and copy.
args.keyslist of keysFor remove: the keys to delete. Without it, the whole node goes.
args.templatebooleanFor update with a string value: when true, each {{value}} in it is replaced by the target's current value, so "Deprecated: {{value}}" prefixes a description. The other commands ignore it.
Commands
What they're for
The common case is injecting spec extensions that have no dedicated control:
| Goal | Transform |
|---|---|
| Rename a generated model | merge x-octri-model onto the schema |
| Mark an enum value deprecated | merge x-octri-enum-deprecations onto the enum schema |
| Leave an operation out of some languages | merge x-octri-skip onto the operation |
| Mark an operation deprecated | Studio has a control for this; use that instead |
| Drop an endpoint from the spec | Studio's inclusion toggle is safer; use that instead |
Deprecation, inclusion, method names, and doc comments all have first-class per-endpoint controls. They're safer than a transform because they can't silently miss.
They fail quietly
Transforms are applied to the raw spec. A target that matches nothing does nothing, and the build succeeds. Rename a schema in your spec and a transform pointing at the old name stops applying, silently, until someone notices the model name reverted.
Re-check your transforms after any significant spec change, and write reason on every one so the next person knows what it was protecting.
Order matters
Transforms run in sequence. A remove that deletes a node makes a later transform targeting it a no-op. Keep the list short and ordered from broad to narrow.
When to fix the spec instead
Transforms are a patch over a spec you don't control. If you own the spec, fix it at source: the transform is invisible to everyone reading your OpenAPI document, and it's one more thing to keep in sync.
Most of what teams reach for a transform to paper over is a habit worth fixing upstream instead. Ten habits for writing great OpenAPI specs covers the ones that matter most downstream.
From the CLI
octri sdk settings get --key transforms prints your transforms, and octri sdk settings set transforms '[…]' replaces the list with the JSON you give. See SDK commands.