Skip to content

feat(Spec): add plain OpenAPI 3.2 fields - #2149

Draft
DerManoMann wants to merge 4 commits into
zircote:masterfrom
DerManoMann:feat/spec-3.2-fields
Draft

feat(Spec): add plain OpenAPI 3.2 fields#2149
DerManoMann wants to merge 4 commits into
zircote:masterfrom
DerManoMann:feat/spec-3.2-fields

Conversation

@DerManoMann

@DerManoMann DerManoMann commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Overview

This adds 3.2 fields that need nothing but a property and somewhere to emit it. Spec
attributes stay version-agnostic — one DTO carries every version's fields and the
per-version compiler decides what to emit — so each field is carried on the DTO and
emitted only by OpenApi32Compiler. A 3.0 or 3.1 document drops it silently, the way it
already drops Tag::$parent.

Along the way this settles a convention that was never written down: a mixed property
cannot use null to mean "unset", because null is a legal value for it.

Changes

  • OpenApi::$self — a URI identifying the document, and the base URI for relative
    references
  • Server::$name — a unique name for the server, for use in tooling
  • Response::$summary — a short summary alongside the existing description
  • Example::$dataValue — the example value before serialization
  • Example::$serializedValue — the example value after serialization
  • Security\Scheme::$deprecated — applies to every scheme type
  • Security\Scheme::$oauth2MetadataUrl — the RFC 8414 authorization server metadata URL,
    emitted for oauth2 schemes only
  • deprecated and oauth2MetadataUrl also reach the typed Security\Scheme\* subtypes
  • The Example Object's mutual-exclusion rules are validated with a warning, matching the
    existing License url/identifier check
  • Example::$value and Link::$requestBody move to Undefined::UNDEFINED, the sentinel
    every other mixed property already used, so both can now express an explicit null.
    Compiled output is otherwise unchanged, and HybridBridge passes both straight through
    instead of translating them
  • The convention is written up in docs/dev/pipeline.md
  • A redundant inline @var on OpenApi::$security is dropped

`Example::$value` and `Link::$requestBody` were the last two `mixed` properties
defaulting to `null`, and so could not express an explicit `null`. Compiled output is
unchanged.

The convention, and why it exists, is now in `docs/dev/pipeline.md` under "`null` means
unset, except where `null` is a value"; `UndefinedDefaultsTest` asserts it.
`OpenApi::$self`, `Server::$name`, `Response::$summary`,
`Example::$dataValue`/`$serializedValue` and
`Security\Scheme::$deprecated`/`$oauth2MetadataUrl`. Each is carried on the
version-agnostic DTO and emitted only by `OpenApi32Compiler`, so 3.0 and 3.1 drop them
the way they already drop `Tag::$parent`. `deprecated` and `oauth2MetadataUrl` also reach
the typed `Security\Scheme\*` subtypes. The Example Object's mutual-exclusion rules are
validated with a warning, matching the existing License `url`/`identifier` check.

`MediaType::$description` is deliberately absent: it appears in the 3.2 JSON Schema but
not in the spec's fixed-field table for the Media Type Object, and redocly rejects it.
Fourteen `CompilerTest` cases pairing "3.2 emits" with "3.1 omits" become one
spec-mode fixture and three expected documents, since `ScratchTest`'s version matrix
asserts the omissions without any test code. The emitted documents now go through
`composer redocly`, which nothing else in the suite does for compiler output.

Two cases could not move and stay in `CompilerTest`: the `$self` key position, because
`assertSpecEquals` compares maps order-independently, and the mutual-exclusion warnings,
which need a document redocly rejects.

`Spec32.php` holds no fixture material — discovery globs `Scratch/*.php` and skips
`-spec` names, so the classic file has to exist for the spec one to be found. With no
classic YAMLs every classic combination skips and the anchor is never loaded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant