Context
Follow-up from #155.
#155 asked for discriminator.mapping values to be inlined like $ref nodes. That is not valid OpenAPI: the Discriminator Object types mapping as Map[string, string] (schema name or URI reference). Replacing those strings with Schema objects fails validation (as the #155 reporter found when trying a local patch).
Internal fragment refs such as #/components/schemas/Foo should remain strings. Leaving them alone during ResolvingParser inlining is correct.
The real gap is bundling / external URI rewrite: when mapping values point at external files (or relative paths), those strings can become dangling after $ref targets are pulled into components, while adjacent oneOf/anyOf $refs are rewritten or inlined.
This matches the problem space Redocly addressed in redocly-cli#1602 / PR #1666: rewrite mapping strings to local #/components/schemas/... (or equivalent), do not inline schema objects into mapping.
Expected Behaviour
When resolving/bundling a multi-file spec, discriminator.mapping URI values that refer to external (or relative) schemas should be rewritten to stable local string references that still point at the bundled targets.
Minimal Example Spec
openapi: 3.0.3
info:
title: Discriminator bundling
version: 1.0.0
paths:
/pets:
get:
responses:
'200':
description: ok
content:
application/json:
schema:
$ref: ./pet.yaml
pet.yaml:
oneOf:
- $ref: ./cat.yaml
- $ref: ./dog.yaml
discriminator:
propertyName: petType
mapping:
cat: ./cat.yaml
dog: ./dog.yaml
After bundling (illustrative), mapping values should be rewritten to local component URIs/names, e.g.:
mapping:
cat: '#/components/schemas/cat'
dog: '#/components/schemas/dog'
…not replaced with inlined Schema objects.
Actual Behaviour
reference_iterator / RefResolver only discover JSON Reference objects ({"$ref": "..."}). Bare strings under discriminator.mapping are ignored, so external/relative mapping URIs are left unchanged even when the referenced schemas are bundled elsewhere.
Proposed Solutions
-
String→string rewrite (preferred for bundling)
- Discover URI-form values under
discriminator.mapping (and optionally schema-name form left alone).
- Resolve each URI with the same base-URL process as
$ref (OAS recommends the $ref process for URI-form mapping).
- Ensure the target schema is present under
components.schemas (same as other bundled externals).
- Replace the mapping value with a local string such as
#/components/schemas/<name> (or a component name, if that is the chosen bundling convention).
- Keep post-resolve validation enabled; mapping values must remain strings.
-
Align with existing TRANSLATE_EXTERNAL
- Today
TRANSLATE_EXTERNAL rewrites external $ref sites into local component $refs.
- Extend that mode (or a dedicated bundling path) so
discriminator.mapping URI strings get the same rewrite treatment.
-
Do not
- Inline Schema objects into
mapping.
- Change behaviour for already-valid internal
#/components/... mapping strings unless a rename/collision policy requires updating them.
Acceptance Criteria
References
Context
Follow-up from #155.
#155 asked for
discriminator.mappingvalues to be inlined like$refnodes. That is not valid OpenAPI: the Discriminator Object typesmappingasMap[string, string](schema name or URI reference). Replacing those strings with Schema objects fails validation (as the #155 reporter found when trying a local patch).Internal fragment refs such as
#/components/schemas/Fooshould remain strings. Leaving them alone duringResolvingParserinlining is correct.The real gap is bundling / external URI rewrite: when mapping values point at external files (or relative paths), those strings can become dangling after
$reftargets are pulled intocomponents, while adjacentoneOf/anyOf$refs are rewritten or inlined.This matches the problem space Redocly addressed in redocly-cli#1602 / PR #1666: rewrite mapping strings to local
#/components/schemas/...(or equivalent), do not inline schema objects intomapping.Expected Behaviour
When resolving/bundling a multi-file spec,
discriminator.mappingURI values that refer to external (or relative) schemas should be rewritten to stable local string references that still point at the bundled targets.Minimal Example Spec
pet.yaml:After bundling (illustrative), mapping values should be rewritten to local component URIs/names, e.g.:
…not replaced with inlined Schema objects.
Actual Behaviour
reference_iterator/RefResolveronly discover JSON Reference objects ({"$ref": "..."}). Bare strings underdiscriminator.mappingare ignored, so external/relative mapping URIs are left unchanged even when the referenced schemas are bundled elsewhere.Proposed Solutions
String→string rewrite (preferred for bundling)
discriminator.mapping(and optionally schema-name form left alone).$ref(OAS recommends the$refprocess for URI-form mapping).components.schemas(same as other bundled externals).#/components/schemas/<name>(or a component name, if that is the chosen bundling convention).Align with existing
TRANSLATE_EXTERNALTRANSLATE_EXTERNALrewrites external$refsites into local component$refs.discriminator.mappingURI strings get the same rewrite treatment.Do not
mapping.#/components/...mapping strings unless a rename/collision policy requires updating them.Acceptance Criteria
discriminator.mappingURIs are rewritten to local string refs when bundling/resolving multi-file specs.openapi-spec-validator.oneOf/anyOf$refresolution continues to work as today.References
mappingis listed among fields that identify referenced elements; values stay strings