Skip to content

Commit

Permalink
[Bugfix] Fix complex intersections of allOf/anyOf/properties/required (
Browse files Browse the repository at this point in the history
…fix #381)
  • Loading branch information
bcherny committed Jan 21, 2024
1 parent 6adcad9 commit 6082085
Show file tree
Hide file tree
Showing 6 changed files with 33,987 additions and 509 deletions.
34 changes: 34 additions & 0 deletions src/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {appendToDescription, escapeBlockComment, isSchemaLike, justName, toSafeS
import {Options} from './'
import {DereferencedPaths} from './resolver'
import {isDeepStrictEqual} from 'util'
import {typesOfSchema} from './typesOfSchema'

type Rule = (
schema: LinkedJSONSchema,
Expand Down Expand Up @@ -222,6 +223,39 @@ rules.set('Transform const to singleton enum', schema => {
}
})

rules.set('Propagate additionalProperties=false to all intersection members', schema => {
if (schema.additionalProperties !== false) {
return
}
schema.allOf?.forEach(_ => {
if ('additionalProperties' in _) {
return
}
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
return
}
_.additionalProperties = false
})
schema.anyOf?.forEach(_ => {
if ('additionalProperties' in _) {
return
}
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
return
}
_.additionalProperties = false
})
schema.oneOf?.forEach(_ => {
if ('additionalProperties' in _) {
return
}
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
return
}
_.additionalProperties = false
})
})

export function normalize(
rootSchema: LinkedJSONSchema,
dereferencedPaths: DereferencedPaths,
Expand Down
14 changes: 14 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,20 @@ via the \`patternProperty\` "${key.replace('*/', '*\\/')}".`
)
}

if (schema.required) {
asts = asts.concat(
map(schema.required, key => {
return {
ast: {type: 'UNKNOWN'},
isPatternProperty: false,
isRequired: true,
isUnreachableDefinition: false,
keyName: key,
}
}),
)
}

if (options.unreachableDefinitions) {
asts = asts.concat(
map(schema.$defs, (value, key: string) => {
Expand Down
4 changes: 2 additions & 2 deletions src/typesOfSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ const matchers: Record<SchemaType, (schema: JSONSchema) => boolean> = {
}
return 'enum' in schema
},
UNNAMED_SCHEMA() {
return false // Explicitly handled as the default case
UNNAMED_SCHEMA(schema) {
return !('$id' in schema) && ('patternProperties' in schema || 'properties' in schema || 'required' in schema)
},
UNTYPED_ARRAY(schema) {
return schema.type === 'array' && !('items' in schema)
Expand Down

0 comments on commit 6082085

Please sign in to comment.