Skip to content

Commit 997940d

Browse files
improved state tracking
1 parent fda99f0 commit 997940d

File tree

1 file changed

+45
-44
lines changed

1 file changed

+45
-44
lines changed

src/middlewares/parsers/schema.preprocessor.ts

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,19 @@ type VisitorTypesWithReference = {
6868
: never;
6969
}[keyof VisitorObjects];
7070

71+
type DiscriminatorState = {
72+
discriminator?: string;
73+
options?: { option: any; ref: any }[];
74+
properties?: {
75+
[p: string]: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
76+
};
77+
required?: string[];
78+
};
79+
7180
class VisitorNode<NodeType extends VisitorTypes> {
81+
public discriminator: DiscriminatorState = {};
82+
public originalRef?: string;
83+
7284
constructor(
7385
public type: NodeType,
7486
public object: VisitorObjects[NodeType] | undefined,
@@ -162,16 +174,7 @@ type VisitorState = {
162174

163175
type State<Type extends 'request' | 'response'> = {
164176
type: Type;
165-
discriminator: {
166-
discriminator?: string;
167-
options?: { option: any; ref: any }[];
168-
properties?: {
169-
[p: string]: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
170-
};
171-
required?: string[];
172-
};
173177
path: string[];
174-
originalObject?: OpenAPIObject;
175178
};
176179

177180
export class SchemaPreprocessor<
@@ -219,6 +222,8 @@ export class SchemaPreprocessor<
219222
}
220223

221224
if (isReferenceNode(node) && isReferenceObject(node.object)) {
225+
node.originalRef = node.object.$ref;
226+
222227
const resolvedObject = this.resolveObject<typeof node.type>(
223228
node.object,
224229
);
@@ -233,9 +238,6 @@ export class SchemaPreprocessor<
233238

234239
seenObjects.add(node.object);
235240

236-
state.request.originalObject = node.object;
237-
state.response.originalObject = node.object;
238-
239241
this.visitNode(parent, node, state);
240242

241243
let children: VisitorNode<any>[];
@@ -282,8 +284,8 @@ export class SchemaPreprocessor<
282284
};
283285

284286
traverse(undefined, root, {
285-
request: { type: 'request', discriminator: {}, path: [] },
286-
response: { type: 'response', discriminator: {}, path: [] },
287+
request: { type: 'request', path: [] },
288+
response: { type: 'response', path: [] },
287289
});
288290
}
289291

@@ -408,30 +410,26 @@ export class SchemaPreprocessor<
408410
this.handleWriteonly(parentSchema, nodeSchema, options);
409411
}
410412

411-
this.processDiscriminator(parentSchema, nodeSchema, options);
413+
this.processDiscriminator(parent, node);
412414
}
413415
}
414416

415417
private processDiscriminator(
416-
parentSchema: VisitorObjects['schema'],
417-
nodeSchema: VisitorObjects['schema'],
418-
state: State<'request' | 'response'>,
418+
parent: VisitorNode<'schema'> | undefined,
419+
node: VisitorNode<'schema'>,
419420
): void {
420-
const o = state.discriminator;
421-
const schemaObj = <OpenAPIV3.CompositionSchemaObject>nodeSchema;
421+
const nodeState = node.discriminator;
422+
const schemaObj = <OpenAPIV3.CompositionSchemaObject>node.object;
423+
422424
const xOf =
423425
schemaObj.oneOf !== undefined
424426
? 'oneOf'
425427
: schemaObj.anyOf
426428
? 'anyOf'
427429
: undefined;
428430

429-
if (
430-
xOf &&
431-
schemaObj.discriminator?.propertyName !== undefined &&
432-
o.discriminator === undefined
433-
) {
434-
o.options = schemaObj[xOf].flatMap((refObject) => {
431+
if (xOf && schemaObj.discriminator?.propertyName !== undefined) {
432+
nodeState.options = schemaObj[xOf].flatMap((refObject) => {
435433
if (refObject['$ref'] === undefined) {
436434
return [];
437435
}
@@ -444,29 +442,31 @@ export class SchemaPreprocessor<
444442
? keys.map((option) => ({ option, ref }))
445443
: [{ option: ref, ref }];
446444
});
447-
o.discriminator = schemaObj.discriminator?.propertyName;
448-
o.properties = {
449-
...(o.properties ?? {}),
445+
nodeState.discriminator = schemaObj.discriminator?.propertyName;
446+
nodeState.properties = {
447+
...(nodeState.properties ?? {}),
450448
...(schemaObj.properties ?? {}),
451449
};
452-
o.required = Array.from(
453-
new Set((o.required ?? []).concat(schemaObj.required ?? [])),
450+
nodeState.required = Array.from(
451+
new Set((nodeState.required ?? []).concat(schemaObj.required ?? [])),
454452
);
455453
}
456454

457455
if (xOf) return;
458456

459-
if (o.discriminator) {
460-
o.properties = {
461-
...(o.properties ?? {}),
457+
const parentState = parent?.discriminator;
458+
459+
if (parent && parentState && parentState.discriminator) {
460+
parentState.properties = {
461+
...(parentState.properties ?? {}),
462462
...(schemaObj.properties ?? {}),
463463
};
464-
o.required = Array.from(
465-
new Set((o.required ?? []).concat(schemaObj.required ?? [])),
464+
parentState.required = Array.from(
465+
new Set((parentState.required ?? []).concat(schemaObj.required ?? [])),
466466
);
467467

468-
const ancestor: any = parentSchema;
469-
const ref = state.originalObject['$ref'];
468+
const ancestor: any = parent.object;
469+
const ref = node.originalRef;
470470

471471
if (!ref) return;
472472

@@ -483,14 +483,14 @@ export class SchemaPreprocessor<
483483
const newSchema = JSON.parse(JSON.stringify(schemaObj));
484484

485485
const newProperties = {
486-
...(o.properties ?? {}),
486+
...(parentState.properties ?? {}),
487487
...(newSchema.properties ?? {}),
488488
};
489489
if (Object.keys(newProperties).length > 0) {
490490
newSchema.properties = newProperties;
491491
}
492492

493-
newSchema.required = o.required;
493+
newSchema.required = parentState.required;
494494
if (newSchema.required.length === 0) {
495495
delete newSchema.required;
496496
}
@@ -500,8 +500,8 @@ export class SchemaPreprocessor<
500500
enumerable: false,
501501
value: ancestor._discriminator ?? {
502502
validators: {},
503-
options: o.options,
504-
property: o.discriminator,
503+
options: parentState.options,
504+
property: parentState.discriminator,
505505
},
506506
});
507507

@@ -510,9 +510,10 @@ export class SchemaPreprocessor<
510510
this.ajv.compile(newSchema);
511511
}
512512
}
513+
513514
//reset data
514-
o.properties = {};
515-
delete o.required;
515+
//parentState.properties = {};
516+
//delete parentState.required;
516517
}
517518
}
518519

0 commit comments

Comments
 (0)