We use Spectral at ReadMe and love that it's done to help clean up some API documentation of ours that had become a bit messy over the years. Here's the config file we use and some custom plugins I've written that help to ensure that we have: consistent sentence punctuation in descriptions, consistent usage of slug terminology, and incorporating Alex to ensure that our API docs have considerate and inclusive language.
Last active
July 14, 2022 23:54
-
-
Save erunion/92f8377700110b7e8bb81aa7faf58bf9 to your computer and use it in GitHub Desktop.
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
extends: | |
- spectral:oas | |
- spectral:asyncapi | |
functionsDir: .openapi/spectralRules | |
functions: | |
- alex | |
- sentencePunctuation | |
- standardizedSlugDescriptions | |
rules: | |
# Spectral has trouble understanding how we compose our error component schemas and thinks that | |
# they're unused. They aren't! | |
oas3-unused-component: off | |
alex-component-summary: | |
description: Component schema summaries should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.components.. | |
type: style | |
then: | |
field: summary | |
function: alex | |
alex-component-descriptions: | |
description: Component schema description should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.components.. | |
type: style | |
then: | |
field: description | |
function: alex | |
alex-operation-summary: | |
description: Operation summaries should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.paths..[get,put,post,delete,options,head,patch,trace]. | |
type: style | |
then: | |
field: summary | |
function: alex | |
alex-operation-description: | |
description: Operation descriptions should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.paths..[get,put,post,delete,options,head,patch,trace]. | |
type: style | |
then: | |
field: description | |
function: alex | |
alex-parameter: | |
description: Operation parameters should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.paths..[get,put,post,delete,options,head,patch,trace]..parameters.. | |
type: style | |
then: | |
field: description | |
function: alex | |
alex-response: | |
description: Operation responses should have inclusive and considerate language. | |
message: "{{error}}" | |
severity: error | |
given: $.paths..[get,put,post,delete,options,head,patch,trace]..responses.. | |
type: style | |
then: | |
field: description | |
function: alex | |
description-sentence-punctuation: | |
description: Descriptions should have ending punctuation. | |
message: "{{error}}" | |
severity: info | |
given: $.paths..[get,put,post,delete,options,head,patch,trace]..description | |
type: style | |
then: | |
field: description | |
function: sentencePunctuation | |
standard-slug-description: | |
description: "`slug` parameters should have standardized descriptions." | |
message: "{{error}}" | |
severity: info | |
given: | |
- $..parameters.. | |
then: | |
function: standardizedSlugDescriptions |
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
const { text } = require('alex'); | |
/** | |
* Ensure that a given string has considerate and inclusive language. | |
* | |
* @see {@link https://alexjs.com/} | |
* @param {string} input | |
*/ | |
export default async function alex(input, options, context) { | |
const errors = text(input).messages; | |
if (!errors.length) { | |
return []; | |
} | |
return Object.values(errors) | |
.map(err => { | |
// We use `invalid` in some response error component descriptions and within the context that | |
// they're used they're fine. | |
if (err.ruleId === 'invalid') { | |
return false; | |
} | |
return { | |
message: err.reason, | |
path: context.path, | |
}; | |
}) | |
.filter(Boolean); | |
} |
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
/** | |
* Ensure that a given string has ending punctuation (if it's longer than three words). | |
* | |
* @param {string} input | |
*/ | |
export default async function standardizedSlugDescription(input) { | |
if (input.split(' ').length <= 3) { | |
return []; | |
} else if (!input.match(/^(.*)[.?!/]$/m)) { | |
return [ | |
{ | |
message: `\`${input}\` does not have trailing punctuation.`, | |
}, | |
]; | |
} | |
return []; | |
} |
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
/** | |
* All of our `slug` parameters should have a standardized description that reads something like | |
* the following: | |
* | |
* A URL-safe representation of the category title. Slugs must be all lowercase, and replace | |
* spaces with hyphens. For example, for the the category "Getting Started", enter the slug | |
* "getting-started" | |
* | |
* @param {OpenAPI.ParameterObject} input | |
*/ | |
export default async function standardizedSlugDescription(input) { | |
if ( | |
input.name === 'slug' && | |
!input.description.match( | |
/^A URL-safe representation of the (.*) title. Slugs must be all lowercase, and replace spaces with hyphens. For example, for the the (.*) "([\w ]+)", enter the slug "([a-z-]+)".$/ | |
) | |
) { | |
return [ | |
{ | |
message: `\`${input.name}\` does not have our standardized description for slugs.`, | |
}, | |
]; | |
} | |
return []; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment