Skip to content

Commit 6082085

Browse files
committed
[Bugfix] Fix complex intersections of allOf/anyOf/properties/required (fix #381)
1 parent 6adcad9 commit 6082085

File tree

6 files changed

+33987
-509
lines changed

6 files changed

+33987
-509
lines changed

src/normalizer.ts

+34
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {appendToDescription, escapeBlockComment, isSchemaLike, justName, toSafeS
33
import {Options} from './'
44
import {DereferencedPaths} from './resolver'
55
import {isDeepStrictEqual} from 'util'
6+
import {typesOfSchema} from './typesOfSchema'
67

78
type Rule = (
89
schema: LinkedJSONSchema,
@@ -222,6 +223,39 @@ rules.set('Transform const to singleton enum', schema => {
222223
}
223224
})
224225

226+
rules.set('Propagate additionalProperties=false to all intersection members', schema => {
227+
if (schema.additionalProperties !== false) {
228+
return
229+
}
230+
schema.allOf?.forEach(_ => {
231+
if ('additionalProperties' in _) {
232+
return
233+
}
234+
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
235+
return
236+
}
237+
_.additionalProperties = false
238+
})
239+
schema.anyOf?.forEach(_ => {
240+
if ('additionalProperties' in _) {
241+
return
242+
}
243+
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
244+
return
245+
}
246+
_.additionalProperties = false
247+
})
248+
schema.oneOf?.forEach(_ => {
249+
if ('additionalProperties' in _) {
250+
return
251+
}
252+
if (typesOfSchema(_)[0] !== 'NAMED_SCHEMA' && typesOfSchema(_)[0] !== 'UNNAMED_SCHEMA') {
253+
return
254+
}
255+
_.additionalProperties = false
256+
})
257+
})
258+
225259
export function normalize(
226260
rootSchema: LinkedJSONSchema,
227261
dereferencedPaths: DereferencedPaths,

src/parser.ts

+14
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,20 @@ via the \`patternProperty\` "${key.replace('*/', '*\\/')}".`
427427
)
428428
}
429429

430+
if (schema.required) {
431+
asts = asts.concat(
432+
map(schema.required, key => {
433+
return {
434+
ast: {type: 'UNKNOWN'},
435+
isPatternProperty: false,
436+
isRequired: true,
437+
isUnreachableDefinition: false,
438+
keyName: key,
439+
}
440+
}),
441+
)
442+
}
443+
430444
if (options.unreachableDefinitions) {
431445
asts = asts.concat(
432446
map(schema.$defs, (value, key: string) => {

src/typesOfSchema.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ const matchers: Record<SchemaType, (schema: JSONSchema) => boolean> = {
140140
}
141141
return 'enum' in schema
142142
},
143-
UNNAMED_SCHEMA() {
144-
return false // Explicitly handled as the default case
143+
UNNAMED_SCHEMA(schema) {
144+
return !('$id' in schema) && ('patternProperties' in schema || 'properties' in schema || 'required' in schema)
145145
},
146146
UNTYPED_ARRAY(schema) {
147147
return schema.type === 'array' && !('items' in schema)

0 commit comments

Comments
 (0)