Expand description
TaskFast OpenAPI spec tooling.
The authoritative spec lives at spec/openapi.yaml. The platform team
evolves it against Elixir routes; clients generate from it. A small set of
structural redundancies would cause progenitor to emit distinct Rust types
for schemas that are semantically identical (e.g. multiple {error, message}
objects under different names). This crate’s normalize_spec folds those
aliases into a single canonical shape in memory, leaving the on-disk spec
untouched.
Consumers:
cargo xtask sync-spec(binary) — writes a normalized artifact for inspection.taskfast-client/build.rs— pipes the normalized YAML into progenitor.
§Rewrite rules
Today: every name in ERROR_ALIASES is a structural clone of
#/components/schemas/Error. The normalizer:
- Asserts each alias is byte-for-byte structurally equal to
Error(ignoringdescription/exampledoc-only fields) — drift fails loud. - Rewrites every
$ref: '#/components/schemas/<alias>'to point at#/components/schemas/Error. - Removes the alias definitions from
components.schemas.
Adding a new alias ⇒ append to ERROR_ALIASES. If a schema grows a real
distinguishing field, remove it from ERROR_ALIASES; the drift check
will refuse to normalize otherwise.
§Multipart strip
progenitor 0.9 can’t codegen multipart/form-data request bodies. Rather
than maintain a patched fork, the normalizer drops operations whose request
body declares only multipart variants — today that is
POST /tasks/{task_id}/artifacts (uploadArtifact). The upload path is
hand-rolled in taskfast-client using reqwest::multipart directly; the
Artifact response schema still comes through codegen because it’s
referenced by the surviving GET /tasks/{task_id}/artifacts operation.
The removed operationIds are reported via Report::stripped_operations
so callers can verify nothing unexpected disappeared.
§Multi-media-type request collapse
progenitor 0.x panics (more media types than expected) when a request
body declares more than one content media type. The OAuth endpoints
(POST /oauth2/token, POST /oauth2/revoke) accept both
application/json and application/x-www-form-urlencoded, each pointing
at the same request schema. The normalizer collapses such bodies to a
single preferred media type (application/json when present, else the
first declared), which is lossless here because the variants share a
schema. Runs after the multipart strip so multipart-bearing operations
are already gone and never get collapsed instead of removed. Count surfaced
via Report::request_media_collapsed.
§Error response strip
progenitor 0.9 asserts response_types.len() <= 1 for both the success
and error response sets (see progenitor-impl/src/method.rs —
extract_responses). Nearly every TaskFast operation declares 2–5
distinct error response shapes (Error, ValidationError, ClaimFailure,
etc.), which trips the error-side assertion. Rather than synthesize a
union error type that we’d throw away anyway, the normalizer drops every
non-2xx (and non-default) response before handing the spec to progenitor.
Surfacing of 4xx/5xx failures is the job of taskfast-client::errors::Error,
which reads the response body manually on the way up.
This means the generated client sees every unhappy status as
progenitor_client::Error::UnexpectedResponse(reqwest::Response) — we
re-classify into our typed taskfast_client::errors::Error in the calling layer.
§Closed-object strip
Every additionalProperties: false is removed so generated types ignore
unknown keys — an additive server change must not break installed CLIs
(gh#172).
§Response-enum strip
String enums reachable from success or default response bodies are opened
so additive server enum values decode in released CLIs (gh#176). Request-only
enums stay typed; shared schemas prioritize response tolerance.
§Response-required relax
required lists in response-reachable schemas are cut down to
KEEP_REQUIRED, the fields CLI code reads as plain values. Every other
response property becomes Option, so a server that drops a required field
the CLI never reads no longer breaks released CLIs (gh#178).
Structs§
Constants§
- ERROR_
ALIASES - Schemas known to be structural clones of
#/components/schemas/Error. - KEEP_
REQUIRED - Response properties that stay required:
(schema key, property).
Functions§
- normalize_
spec - Normalize an OpenAPI YAML document: collapse
ERROR_ALIASESintoError. - normalize_
spec_ with_ report - As
normalize_specbut also returns a summary of what changed.