Skip to content

Commit 70e2843

Browse files
committed
Handle readonly properties on arrays.
1 parent b4e3911 commit 70e2843

2 files changed

Lines changed: 17 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 2.0 ##
44
* Split out schema validator to reduce bundle size
5+
* Handle readonly properties on array items
56

67
## 1.2 ##
78
* Add `compile` and `loadCompiled` specs for faster validation

src/middlewares/parsers/schema.preprocessor.ts

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ export class SchemaPreprocessor {
8181
};
8282

8383
// Traverse the schemas
84-
this.traverseSchemas(schemaNodes, (parent, schema, opts) =>
85-
this.schemaVisitor(parent, schema, opts)
84+
this.traverseSchemas(schemaNodes, (parent, schema) =>
85+
this.schemaVisitor(parent, schema)
8686
);
8787
}
8888

@@ -173,6 +173,9 @@ export class SchemaPreprocessor {
173173
const child = new Node(node, s, [...node.path, 'anyOf', `${i}`]);
174174
recurse(node, child, opts);
175175
});
176+
} else if (schema.type === 'array' && schema.items) {
177+
const child = new Node(node, schema.items, [...node.path, 'items']);
178+
recurse(node, child, opts);
176179
} else if (schema.properties) {
177180
Object.entries(schema.properties).forEach(([id, cschema]) => {
178181
const path = [...node.path, 'properties', id];
@@ -202,26 +205,10 @@ export class SchemaPreprocessor {
202205

203206
private schemaVisitor(
204207
parent: SchemaObjectNode,
205-
node: SchemaObjectNode,
206-
opts: TraversalStates
208+
node: SchemaObjectNode
207209
) {
208-
const pschemas = [parent?.schema];
209-
const nschemas = [node.schema];
210-
211-
// visit the node in both the request and response schema
212-
for (let i = 0; i < nschemas.length; i++) {
213-
const kind = i === 0 ? 'req' : 'res';
214-
const pschema = pschemas[i];
215-
const nschema = nschemas[i];
216-
const options = opts[kind];
217-
options.path = node.path;
218-
219-
if (nschema) {
220-
// This null check should no longer be necessary
221-
this.handleSerDes(pschema, nschema as NonArraySchemaObject);
222-
this.handleReadonly(pschema, nschema, options);
223-
}
224-
}
210+
this.handleSerDes(parent?.schema, node.schema as NonArraySchemaObject);
211+
this.handleReadonly(parent?.schema, node.schema, node.path);
225212
}
226213

227214
private handleSerDes(
@@ -241,21 +228,16 @@ export class SchemaPreprocessor {
241228
private handleReadonly(
242229
parent: OpenAPIV3.SchemaObject,
243230
schema: OpenAPIV3.SchemaObject,
244-
opts
231+
path
245232
) {
246-
if (opts.kind === 'res') {return;}
247-
233+
if (!schema.readOnly) {
234+
return;
235+
}
236+
const prop = path?.[path?.length - 1];
248237
const required = parent?.required ?? [];
249-
const prop = opts?.path?.[opts?.path?.length - 1];
250-
const index = required.indexOf(prop);
251-
if (schema.readOnly && index > -1) {
252-
// remove required if readOnly
253-
parent.required = required
254-
.slice(0, index)
255-
.concat(required.slice(index + 1));
256-
if (parent.required.length === 0) {
257-
delete parent.required;
258-
}
238+
parent.required = required.filter(p => p !== prop);
239+
if (parent.required.length === 0) {
240+
delete parent.required;
259241
}
260242
}
261243

0 commit comments

Comments
 (0)