From f5bfaa945c1adc3e866f8029ca4b6e68c7dec9e0 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 30 Mar 2026 09:34:33 +0200 Subject: [PATCH 1/3] fix: ETU-70068: entur-request-body-description updated to allow description on schema referenced in content.*.schema --- .spectral.yml | 6 +++--- functions/requireRequestBodyDescription.js | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 functions/requireRequestBodyDescription.js diff --git a/.spectral.yml b/.spectral.yml index d13bc69..c12cf62 100644 --- a/.spectral.yml +++ b/.spectral.yml @@ -7,6 +7,7 @@ extends: [spectral:oas] functions: - requireExampleOrRef + - requireRequestBodyDescription rules: # ============================================================================= @@ -94,13 +95,12 @@ rules: function: requireExampleOrRef entur-request-body-description: - message: "Request bodies SHOULD have a description." + message: "Request bodies SHOULD have a description, either directly or on the referenced schema." documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles" severity: warn given: $.paths.*.*.requestBody then: - field: description - function: truthy + function: requireRequestBodyDescription entur-response-body-examples: message: "Response bodies SHOULD include at least one example." diff --git a/functions/requireRequestBodyDescription.js b/functions/requireRequestBodyDescription.js new file mode 100644 index 0000000..5b157bd --- /dev/null +++ b/functions/requireRequestBodyDescription.js @@ -0,0 +1,21 @@ +/** + * Custom Spectral function to check if a request body has a description, + * either directly on the requestBody or on the resolved schema reference. + */ +module.exports = (targetVal) => { + // Check if there's a direct description on the requestBody + if (targetVal.description) { + return; + } + + // Check if the resolved schema has a description + if (targetVal.content) { + for (const mediaType of Object.values(targetVal.content)) { + if (mediaType.schema && mediaType.schema.description) { + return; + } + } + } + + return [{ message: 'Request body SHOULD have a description, either directly or on the referenced schema.' }]; +}; \ No newline at end of file From 93bec134a9ea78e08d2d6324f64977241d6cad0a Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 30 Mar 2026 09:40:41 +0200 Subject: [PATCH 2/3] fix: ETU-70068: entur-request-body-description updated to allow description on schema referenced in array schema which in turn is refernced in content.*.schema --- functions/requireRequestBodyDescription.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/functions/requireRequestBodyDescription.js b/functions/requireRequestBodyDescription.js index 5b157bd..03b5fd2 100644 --- a/functions/requireRequestBodyDescription.js +++ b/functions/requireRequestBodyDescription.js @@ -11,8 +11,14 @@ module.exports = (targetVal) => { // Check if the resolved schema has a description if (targetVal.content) { for (const mediaType of Object.values(targetVal.content)) { - if (mediaType.schema && mediaType.schema.description) { - return; + if (mediaType.schema) { + if (mediaType.schema.description) { + return; + } + // Check if schema is an array with items that have a description + if (mediaType.schema.type === 'array' && mediaType.schema.items && mediaType.schema.items.description) { + return; + } } } } From 40cb86b25be4d22092ff4808fbf830dc114b7931 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 31 Mar 2026 11:09:29 +0200 Subject: [PATCH 3/3] fix: ETU-70068: Checking that All media types have descriptions. --- functions/requireRequestBodyDescription.js | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/functions/requireRequestBodyDescription.js b/functions/requireRequestBodyDescription.js index 03b5fd2..c2b2864 100644 --- a/functions/requireRequestBodyDescription.js +++ b/functions/requireRequestBodyDescription.js @@ -10,17 +10,28 @@ module.exports = (targetVal) => { // Check if the resolved schema has a description if (targetVal.content) { - for (const mediaType of Object.values(targetVal.content)) { - if (mediaType.schema) { - if (mediaType.schema.description) { - return; - } - // Check if schema is an array with items that have a description - if (mediaType.schema.type === 'array' && mediaType.schema.items && mediaType.schema.items.description) { - return; - } + for (const [mediaTypeName, mediaType] of Object.entries(targetVal.content)) { + if (!mediaType.schema) { + return [{ message: `Request body SHOULD have a description, either directly or on the referenced schema. Media type "${mediaTypeName}" has no schema.` }]; } + + const schema = mediaType.schema; + + // Direct description on schema + if (schema.description) { + continue; + } + + // Array schema with items that have a description + if (schema.type === 'array' && schema.items && schema.items.description) { + continue; + } + + return [{ message: `Request body SHOULD have a description, either directly or on the referenced schema. Media type "${mediaTypeName}" is missing a description.` }]; } + + // All media types have descriptions + return; } return [{ message: 'Request body SHOULD have a description, either directly or on the referenced schema.' }];