-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Beheer: voeg spectral linter toe aan standaard
Op dit moment wordt deze linter configuratie gehost op developer.overheid.nl. Echter zijn de beheerders van die website niet verantwoordelijk voor de inhoudelijke implementatie van de linter en de corresponderende design rules. Met deze commit voegen we de configuratie toe. Tevens zijn er wat fixes gemaakt op basis van de huidige COR API die wat incorrecte errors/warnings had. Sommige errors/warnings waren valide en zullen in de COR API zelf moeten worden opgelost. Om ervoor te zorgen dat we inzicht hebben in wat het effect van de linter/design rules zijn, voegen we ook de COR API definitie met verwachte output toe. Deze kunnen op CI worden getest telkens als de linter wordt gewijzigd.
- Loading branch information
1 parent
1603010
commit 8259ae7
Showing
5 changed files
with
1,407 additions
and
0 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,140 @@ | ||
# spectral lint -r https://developer.overheid.nl/static/adr/ruleset.yaml $OAS_URL_OR_FILE | ||
# curl https://developer.overheid.nl/static/adr/ruleset.yaml > .spectral.yml | ||
|
||
extends: spectral:oas | ||
|
||
rules: | ||
|
||
#/core/doc-openapi | ||
openapi3: | ||
severity: error | ||
given: | ||
- "$.['openapi']" | ||
then: | ||
function: pattern | ||
functionOptions: | ||
match: "^3.0.*$" | ||
message: "/core/doc-openapi: Use OpenAPI Specification for documentation: https://logius-standaarden.github.io/API-Design-Rules/#/core/doc-openapi" | ||
|
||
#/core/version-header | ||
missing-version-header: | ||
severity: error | ||
given: $..[responses][?(@property && @property.match(/(2|3)\d\d/))][headers] | ||
then: | ||
field: API-Version | ||
function: truthy | ||
message: "/core/version-header: Return the full version number in a response header: https://logius-standaarden.github.io/API-Design-Rules/#/core/version-header" | ||
|
||
missing-header: | ||
severity: error | ||
given: $..[responses][?(@property && @property.match(/(2|3)\d\d/))] | ||
then: | ||
field: headers | ||
function: truthy | ||
message: "/core/version-header: Return the full version number in a response header: https://logius-standaarden.github.io/API-Design-Rules/#/core/version-header" | ||
|
||
#/core/uri-version | ||
include-major-version-in-uri: | ||
severity: error | ||
given: | ||
- "$.servers[*]" | ||
then: | ||
function: pattern | ||
functionOptions: | ||
match: "\\/v[\\d+]" | ||
field: url | ||
message: "/core/uri-version: Include the major version number in the URI: https://logius-standaarden.github.io/API-Design-Rules/#/core/uri-version" | ||
|
||
#/core/no-trailing-slash | ||
paths-no-trailing-slash: | ||
severity: error | ||
given: | ||
- "$.paths" | ||
then: | ||
function: pattern | ||
functionOptions: | ||
notMatch: "\\/$" | ||
field: "@key" | ||
message: "/core/no-trailing-slash: Leave off trailing slashes from URIs: https://logius-standaarden.github.io/API-Design-Rules/#/core/no-trailing-slash" | ||
|
||
#/core/http-methods | ||
http-methods: | ||
severity: error | ||
given: | ||
- "$.paths[?(@property && @property.match(/(description|summary)/i))]" | ||
then: | ||
function: pattern | ||
functionOptions: | ||
match: "post|put|get|delete|patch|parameters" | ||
field: "@key" | ||
message: "/core/http-methods: Only apply standard HTTP methods: https://logius-standaarden.github.io/API-Design-Rules/#http-methods" | ||
|
||
paths-kebab-case: | ||
severity: warn | ||
message: "{{property}} is not kebab-case." | ||
given: $.paths[*]~ | ||
then: | ||
function: pattern | ||
functionOptions: | ||
match: "^(\/[a-z0-9-.]+|\/{[a-zA-Z0-9_]+})+$" | ||
|
||
schema-camel-case: | ||
severity: warn | ||
message: "Schema name should be CamelCase in {{path}}" | ||
given: >- | ||
$.components.schemas[*]~ | ||
then: | ||
function: casing | ||
functionOptions: | ||
type: pascal | ||
separator: | ||
char: "" | ||
|
||
servers-use-https: | ||
severity: warn | ||
message: "Server URL {{value}} {{error}}." | ||
given: | ||
- $.servers[*] | ||
- $.paths..servers[*] | ||
then: | ||
field: url | ||
function: pattern | ||
functionOptions: | ||
match: ^https://.* | ||
|
||
use-problem-schema: | ||
severity: warn | ||
message: Your schema doesn't seem to match RFC7807. Are you sure it is ok? {{path}} | ||
given: $..[responses][?(@property && @property.match(/^(4|5|default)/))][[schema]].properties | ||
then: | ||
function: schema | ||
functionOptions: | ||
schema: | ||
anyOf: | ||
- type: object | ||
required: | ||
- title | ||
- status | ||
- type: object | ||
required: | ||
- title | ||
- type | ||
- type: object | ||
required: | ||
- type | ||
- status | ||
- type: object | ||
required: | ||
- title | ||
- detail | ||
|
||
property-casing: | ||
severity: warn | ||
given: | ||
- "$.*.schemas[*].properties.[?(@property && @property.match(/_links/i))]" | ||
then: | ||
function: casing | ||
functionOptions: | ||
type: camel | ||
field: "@key" | ||
message: Properties must be lowerCamelCase. |
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,65 @@ | ||
import {exec} from 'child_process'; | ||
import utils from 'util'; | ||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
|
||
const __dirname = import.meta.dirname; | ||
const execute = utils.promisify(exec); | ||
const readFile = utils.promisify(fs.readFile); | ||
const readdir = utils.promisify(fs.readdir); | ||
|
||
const SPECTRAL_RULESET_LOCATION = path.join(__dirname, '.spectral.yml'); | ||
|
||
function computeTestCommand(apiLocation) { | ||
return `spectral lint -r ${SPECTRAL_RULESET_LOCATION} ${apiLocation}/openapi.json` | ||
} | ||
|
||
function removeProcessDir(output) { | ||
return output.replaceAll(__dirname, ''); | ||
} | ||
|
||
async function runCommand(apiLocation) { | ||
try { | ||
const {stdout, stderr} = await execute(computeTestCommand(apiLocation)); | ||
|
||
if (stderr) { | ||
console.error('Found output on stderr:'); | ||
console.error(stderr); | ||
process.exit(1); | ||
} | ||
|
||
if (!stdout) { | ||
console.error('Did not find any output on stdout.'); | ||
process.exit(1); | ||
} | ||
|
||
return removeProcessDir(stdout); | ||
} catch (e) { | ||
console.error('Failed to run command'); | ||
console.error(e); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
async function readExpectedOutput(apiLocation) { | ||
return removeProcessDir(await readFile(path.join(apiLocation, 'expected-output.txt'), {encoding: 'utf-8'})); | ||
} | ||
|
||
async function obtainAllTestcases() { | ||
const apiDirectories = await readdir(path.join(__dirname, 'testcases'), {withFileTypes: true}); | ||
return [...apiDirectories.map(dir => path.join(dir.parentPath, dir.name))]; | ||
} | ||
|
||
for (const apiLocation of await obtainAllTestcases()) { | ||
console.log(`Validating testcase ${apiLocation}`); | ||
const actualOutput = await runCommand(apiLocation); | ||
const expectedOutput = await readExpectedOutput(apiLocation); | ||
|
||
if (actualOutput !== expectedOutput) { | ||
console.error("Failing diff check. Expected:") | ||
console.error(expectedOutput); | ||
console.error("but got") | ||
console.error(actualOutput); | ||
process.exit(1); | ||
} | ||
} |
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,6 @@ | ||
|
||
/testcases/cor-api/openapi.json | ||
181:29 warning paths-kebab-case /laatsteWijziging is not kebab-case. paths./laatsteWijziging | ||
774:30 warning use-problem-schema Your schema doesn't seem to match RFC7807. Are you sure it is ok? #/components/schemas/HealthCheckResponse/properties components.schemas.HealthCheckResponse.properties | ||
|
||
✖ 2 problems (0 errors, 2 warnings, 0 infos, 0 hints) |
Oops, something went wrong.