-
-
Notifications
You must be signed in to change notification settings - Fork 864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for discriminator tag lookup in referenced schemas #2262
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import type {CodeKeywordDefinition, AnySchemaObject, KeywordErrorDefinition} from "../../types" | ||
import type {AnySchemaObject, CodeKeywordDefinition, KeywordErrorDefinition} from "../../types" | ||
import type {KeywordCxt} from "../../compile/validate" | ||
import {_, getProperty, Name} from "../../compile/codegen" | ||
import {DiscrError, DiscrErrorObj} from "../discriminator/types" | ||
import {DiscrError, DiscrErrorObj} from "./types" | ||
import {resolveRef, SchemaEnv} from "../../compile" | ||
import {schemaHasRulesButRef} from "../../compile/util" | ||
|
||
|
@@ -69,18 +69,46 @@ | |
sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, sch?.$ref) | ||
if (sch instanceof SchemaEnv) sch = sch.schema | ||
} | ||
const propSch = sch?.properties?.[tagName] | ||
if (typeof propSch != "object") { | ||
let propSch = sch?.properties?.[tagName] | ||
let hasSubSchRequired = false | ||
if (!propSch && sch?.allOf) { | ||
const {hasRequired, propertyObject} = mapDiscriminatorFromAllOf(propSch, sch) | ||
Check warning on line 75 in lib/vocabularies/discriminator/index.ts GitHub Actions / build (14.x)
Check warning on line 75 in lib/vocabularies/discriminator/index.ts GitHub Actions / build (16.x)
Check warning on line 75 in lib/vocabularies/discriminator/index.ts GitHub Actions / build (18.x)
|
||
hasSubSchRequired = hasRequired | ||
propSch = propertyObject | ||
} | ||
if (!propSch || typeof propSch != "object") { | ||
throw new Error( | ||
`discriminator: oneOf subschemas (or referenced schemas) must have "properties/${tagName}"` | ||
) | ||
} | ||
tagRequired = tagRequired && (topRequired || hasRequired(sch)) | ||
tagRequired = tagRequired && (topRequired || hasRequired(sch) || hasSubSchRequired) | ||
addMappings(propSch, i) | ||
} | ||
if (!tagRequired) throw new Error(`discriminator: "${tagName}" must be required`) | ||
return oneOfMapping | ||
|
||
function mapDiscriminatorFromAllOf( | ||
propSch: any, | ||
sch: any | ||
): {hasRequired: boolean; propertyObject: any} { | ||
let subSchObj: any = null | ||
for (const subSch of sch.allOf) { | ||
if (subSch?.properties) { | ||
propSch = subSch.properties[tagName] | ||
subSchObj = subSch | ||
} else if (subSch?.$ref) { | ||
subSchObj = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, subSch.$ref) | ||
if (subSchObj instanceof SchemaEnv) subSchObj = subSchObj.schema | ||
propSch = subSchObj?.properties?.[tagName] | ||
} | ||
if (propSch) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it possible to move the check out of |
||
//found discriminator mapping in one of the allOf objects, stop searching | ||
return {hasRequired: hasRequired(subSchObj), propertyObject: propSch} | ||
} | ||
} | ||
return {hasRequired: false, propertyObject: null} | ||
} | ||
|
||
function hasRequired({required}: AnySchemaObject): boolean { | ||
return Array.isArray(required) && required.includes(tagName) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: the GitHubActions warnings, maybe we can rename this key or avoid the destructuring and just use a constant for the returned object and reference each key in the following lines?
E.g.