diff --git a/src/middlewares/parsers/schema.preprocessor.ts b/src/middlewares/parsers/schema.preprocessor.ts index 8d9d8948..8e14f4c0 100644 --- a/src/middlewares/parsers/schema.preprocessor.ts +++ b/src/middlewares/parsers/schema.preprocessor.ts @@ -287,6 +287,7 @@ export class SchemaPreprocessor { // This null check should no longer be necessary this.handleSerDes(pschema, nschema, options); this.handleReadonly(pschema, nschema, options); + this.handleWriteonly(pschema, nschema, options); this.processDiscriminator(pschema, nschema, options); this.removeExamples(pschema, nschema, options) } @@ -479,6 +480,27 @@ export class SchemaPreprocessor { } } + private handleWriteonly( + parent: OpenAPIV3.SchemaObject, + schema: OpenAPIV3.SchemaObject, + opts, + ) { + if (opts.kind === 'req') return; + + const required = parent?.required ?? []; + const prop = opts?.path?.[opts?.path?.length - 1]; + const index = required.indexOf(prop); + if (schema.writeOnly && index > -1) { + // remove required if writeOnly + parent.required = required + .slice(0, index) + .concat(required.slice(index + 1)); + if (parent.required.length === 0) { + delete parent.required; + } + } + } + /** * extract all requestBodies' schemas from an operation * @param op diff --git a/test/resources/write.only.yaml b/test/resources/write.only.yaml index 64db4be3..cf8d62e1 100644 --- a/test/resources/write.only.yaml +++ b/test/resources/write.only.yaml @@ -95,6 +95,8 @@ components: # TODO add nested test ProductNested: type: object + required: + - "password" properties: id: type: string @@ -117,9 +119,14 @@ components: type: array items: $ref: '#/components/schemas/Review' + password: + type: string + writeOnly: true Review: type: object + required: + - "review_password" properties: id: type: integer @@ -132,3 +139,6 @@ components: writeOnly: true rating: type: integer + review_password: + type: string + writeOnly: true diff --git a/test/write.only.spec.ts b/test/write.only.spec.ts index 04b6d4b2..57870880 100644 --- a/test/write.only.spec.ts +++ b/test/write.only.spec.ts @@ -86,6 +86,7 @@ describe(packageJson.name, () => { name: 'some name', role: 'admin', price: 10.99, + password: 'password_value' }) .expect(200)); @@ -96,9 +97,11 @@ describe(packageJson.name, () => { .send({ name: 'some name', price: 10.99, + password: 'password_value', reviews: [ { rating: 5, + review_password: 'review_password_value' }, ], })