What a plugin is handed on stdin (← goctl's plugin.Plugin): the parsed specunder api, the .api file it was read from, the --style naming template,and the directory the generated tree goes under.
Parse a plugin's stdout into the files to write. Two shapes are accepted: a barearray [{path, content}, …], or an object {"files": [ … ]} (goctl-styleenvelope). An element missing path or content is skipped. The list preservesthe plugin's order.
Split a plugin invocation into the program to run and the arguments to run itwith, the way goctl reads its -plugin value: the first whitespace-separatedword is the executable, the rest are its argv. A quoted word keeps its spaces.
What a plugin run will actually write: the files whose path is safe, and a noteper file that was refused or superseded. A later file for a path an earlier onealready claimed is refused rather than silently overwriting it — a plugin thatemits the same file twice has a bug, and the report should say so rather thanleave a coin-flip in the output.
The plugin request as a two-space-indented JSON string, ready to write to theplugin's stdin: goctl's four keys — the spec under Api, plus the file it wasread from, the --style template and the output directory, which is everythinga plugin needs to decide where its output goes and what to call it.
Whether a path a plugin supplies lands inside the directory mctl writes to. Aplugin runs as its own process and its reply is arbitrary text, so the one thingmctl must not do is believe it: ../../.ssh/authorized_keys, /etc/passwd andC:/Windows/system32/… are all accepted by a naive writer, and all three writewhere a code generator has no business writing. Only a relative path with no ..segment is allowed; a path with one is refused and named in the run's report.
Reconstruct a Spec from the request JSON — the reader a plugin written inMoonBit uses on its stdin. The whole request ({Api, ApiFilePath, Style, Dir})and a bare spec are both accepted, so a plugin that wants nothing but the routesneed not unwrap the envelope. Missing or mistyped members degrade to emptyrather than raising, so a partial request still parses.
Serialise a Spec into the plugin request JSON. The shape mirrors the Specitself — service, routes (verb/path/handler/summary, plus thegroup the route was declared under), types (name plus fields ofname/type) and groups — so a plugin in any language parses it with anordinary JSON reader. type_ is written as type, the name a caller expects.