-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add new spectral
discriminator
rule and remove old rule (#367)
ruleset: add 'discriminator' rule to ruleset This rule verifies that the 'propertyName' value of the discriminator is present in each subschema. validator: remove broken discriminator rule in favor of new spectral rule This rule was buggy and not previously configurable. The same rule with identical (albeit fixed) behavior is now available in our Spectral ruleset under the name 'discriminator' and is configurable.
- Loading branch information
Showing
21 changed files
with
978 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// a group of predefined "collections" of OpenAPI locations to validate | ||
// helpful when the same group of locations needs to be used by multiple rules | ||
|
||
// a collection of locations where a JSON Schema object can be *used*. | ||
// | ||
// note that this does not include "components.schemas" to avoid duplication. | ||
// this collection should be used in a rule that has "resolved" set to "true". | ||
// we separately validate that all schemas in "components" need to be used. | ||
const schemas = [ | ||
'$.paths[*][parameters][*].schema', | ||
'$.paths[*][parameters][*].content[*].schema', | ||
'$.paths[*][*][parameters][*].schema', | ||
'$.paths[*][*][parameters,responses][*].content[*].schema', | ||
'$.paths[*][*][requestBody].content[*].schema' | ||
]; | ||
|
||
module.exports = { | ||
schemas | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Assertation 1: | ||
// if discriminator exist inside schema object, it must be of type Object | ||
// enforced by Spectral's oas3-schema rule | ||
|
||
// Assertion 2: | ||
// discriminator object must have a field name propertyName | ||
// enforced by Spectral's oas3-schema rule | ||
|
||
// Assertation 3: | ||
// propertyName is of type string | ||
// enforced by Spectral's oas3-schema rule | ||
|
||
// Assertation 4: | ||
// properties inside a schema object must include propertyName from discriminator object | ||
|
||
const { checkSubschemasForProperty, validateSubschemas } = require('../utils'); | ||
|
||
module.exports = function(schema, _opts, { path }) { | ||
return validateSubschemas(schema, path, validateDiscriminators); | ||
}; | ||
|
||
function validateDiscriminators(schema, path) { | ||
const errors = []; | ||
|
||
const { discriminator } = schema; | ||
if (!discriminator || !typeof discriminator === 'object') { | ||
return errors; | ||
} | ||
|
||
const { propertyName } = discriminator; | ||
if (!checkSubschemasForProperty(schema, propertyName)) { | ||
errors.push({ | ||
message: | ||
'The discriminator property name used must be defined in this schema', | ||
path: [...path, 'discriminator', 'propertyName'] | ||
}); | ||
} | ||
|
||
return errors; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const { oas3 } = require('@stoplight/spectral-formats'); | ||
const { discriminator } = require('../functions'); | ||
const { schemas } = require('../collections'); | ||
|
||
module.exports = { | ||
description: 'The discriminator property name must be defined in this schema', | ||
message: '{{error}}', | ||
given: schemas, | ||
severity: 'error', | ||
formats: [oas3], | ||
resolved: true, | ||
then: { | ||
function: discriminator | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const checkSubschemasForProperty = (schema, name) => { | ||
if (!schema) { | ||
return false; | ||
} | ||
|
||
let propertyIsDefined = false; | ||
|
||
// first check the properties | ||
if (schema.properties) { | ||
propertyIsDefined = name in schema.properties; | ||
} else if (schema.oneOf || schema.anyOf) { | ||
// every schema in a oneOf or anyOf must contain the property | ||
const subschemas = schema.oneOf || schema.anyOf; | ||
if (Array.isArray(subschemas)) { | ||
propertyIsDefined = true; | ||
for (const s of subschemas) { | ||
if (!checkSubschemasForProperty(s, name)) { | ||
propertyIsDefined = false; | ||
break; | ||
} | ||
} | ||
} | ||
} else if (Array.isArray(schema.allOf)) { | ||
// at least one schema in an allOf must contain the property | ||
for (const s of schema.allOf) { | ||
if (checkSubschemasForProperty(s, name)) { | ||
propertyIsDefined = true; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return propertyIsDefined; | ||
}; | ||
|
||
module.exports = checkSubschemasForProperty; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const checkSubschemasForProperty = require('./check-subschemas-for-prop'); | ||
const validateSubschemas = require('./validate-subschemas'); | ||
|
||
module.exports = { | ||
checkSubschemasForProperty, | ||
validateSubschemas | ||
}; |
Oops, something went wrong.