From 572a4553207b7c22cad71f027edbdac092a2f140 Mon Sep 17 00:00:00 2001 From: Cesareo <118807053+cesareomacias@users.noreply.github.com> Date: Thu, 13 Feb 2025 16:11:32 +0100 Subject: [PATCH] Create .spectral.yml Added .spectral.yml in order to don't break existing integrations --- .spectral.yml | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 .spectral.yml diff --git a/.spectral.yml b/.spectral.yml new file mode 100644 index 0000000..03bf495 --- /dev/null +++ b/.spectral.yml @@ -0,0 +1,275 @@ +extends: [[spectral:oas, all], [spectral:asyncapi, all]] +documentationUrl: https://github.com/adidas/api-guidelines/blob/master/ruleset.md +rules: + operation-tags: off + operation-operationId: off + operation-success-response: error + + # ----------------------------# + # Adidas OAS v2.0, v3.0 rules # + # ----------------------------# + + adidas-paths-kebab-case: + description: All YAML/JSON paths MUST follow kebab-case + severity: warn + recommended: true + message: "{{property}} is not kebab-case: {{error}}" + given: $.paths[*]~ + then: + function: pattern + functionOptions: + match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces + + adidas-path-parameters-camelCase-alphanumeric: + description: Path parameters MUST follow camelCase + severity: warn + recommended: true + message: "{{property}} path parameter is not camelCase: {{error}}" + given: $..parameters[?(@.in == 'path')].name + then: + function: pattern + functionOptions: + match: "^[a-z][a-zA-Z0-9]+$" + + adidas-definitions-camelCase-alphanumeric: + description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. + severity: error + recommended: true + message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`." + given: $.definitions[*]~ + then: + function: pattern + functionOptions: + match: "/^[a-z$_]{1}[A-Z09$_]*/" + + adidas-properties-camelCase-alphanumeric: + description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. + severity: error + recommended: true + message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`." + given: $.definitions..properties[*]~ + then: + function: pattern + functionOptions: + match: "/^[a-z$_]{1}[A-Z09$_]*/" + + adidas-request-GET-no-body: + description: "A 'GET' request MUST NOT accept a 'body` parameter" + severity: error + given: $.paths..get.parameters..in + then: + function: pattern + functionOptions: + notMatch: "/^body$/" + + adidas-headers-no-x-headers: + description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)." + severity: warn + given: "$..parameters[?(@.in == 'header')].name" + message: "HTTP headers SHOULD NOT include 'X-' prefix." + recommended: true + type: style + then: + function: pattern + functionOptions: + notMatch: "/^(x|X)-/" + + adidas-headers-hyphenated-pascal-case: + description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation + severity: error + given: "$..parameters[?(@.in == 'header')].name" + message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation" + recommended: true + type: style + then: + function: pattern + functionOptions: + match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/" + + # ----------------------# + # Adidas OAS v2.0 rules # + # ----------------------# + + adidas-oas2-protocol-https-only: + description: "ALL requests MUST go through `https` protocol only" + formats: + - oas2 + recommended: true + severity: error + type: "style" + message: "Schemes MUST be https and no other value is allowed." + given: $ + then: + field: schemes + function: schema + functionOptions: + schema: + type: array + items: + type: string + enum: ["https"] + maxItems: 1 + + adidas-oas2-request-support-json: + description: Every request SHOULD support `application/json` media type + formats: + - oas2 + severity: warn + message: "{{description}}: {{error}}" + recommended: true + given: "$..consumes" + then: + function: schema + functionOptions: + schema: + type: array + contains: + type: string + enum: + - application/json + + adidas-oas2-example-exists-in-parameters: + description: All models MUST have a valid example. + severity: error + recommended: true + formats: + - oas2 + message: "{{ property }} MUST have a valid example." + given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]" + then: + function: truthy + + # example-exists-in-definitions covery by oas2-valid-media-example + + adidas-oas2-response-success-hal: # schemes and/or produces + description: "All success responses MUST be of media type `application/hal+json`" + severity: error + given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)] + recommended: true + type: "style" + formats: + - oas2 + message: "Response documents MUST follow application/hal+json: {{error}}" + then: + field: schema + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/HAL.yaml" + + adidas-oas2-response-error-problem: # schemas and/or produces + description: All error responses MUST be of media type `application/problem+json` + severity: error + formats: + - oas2 + given: $.paths..responses[?( @property >= 400 && @property < 600 )] + recommended: true + type: "style" + message: "Error response document MUST follow application/problem+json: {{error}}" + then: + field: schema.example + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/ProblemDetail.yaml" + + # ----------------------# + # Adidas OAS v3.0 rules # + # ----------------------# + + adidas-oas3-request-support-json: + description: Every request MUST support `application/json` media type + formats: + - oas3 + recommended: true + severity: error + message: "{{description}}: {{error}}" + given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^ + then: + function: falsy + + # adidas-oas3-valid-example-in-parameters && adidas-oas3-valid-example-in-definitions covered by oas3-valid-media-example + + adidas-oas3-protocol-https-only: + description: "ALL requests MUST go through `https` protocol only" + formats: + - oas3 + recommended: true + severity: error + message: "Servers MUST be https and no other protocol is allowed." + given: $.servers..url + then: + function: pattern + functionOptions: + match: "/^https:/" + + adidas-oas3-response-success-hal: + description: "All success responses MUST be of media type `application/hal+json` " + severity: error + given: $.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~ + recommended: true + formats: + - oas3 + message: "Response documents MUST be of application/hal+json media types: {{error}}" + then: + function: enumeration + functionOptions: + values: + - application/hal+json + + # sync and async patterns that can return hal OR problem+json + adidas-oas3-response-success-OK: + description: "All success responses MUST be of media type `application/hal+json` or `application/problem+json`" + severity: error + given: $.paths..responses[?( @property == 200 )].content[*]~ + recommended: true + formats: + - oas3 + message: "Response documents MUST be of application/hal+json or application/problem+json media types: {{error}}" + then: + function: enumeration + functionOptions: + values: + - application/hal+json + - application/problem+json + + adidas-oas3-response-success-hal-body: # schemes and/or produces + description: "All success responses MUST follow `application/hal+json` schema" + severity: error + given: $.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")] + recommended: true + type: "style" + formats: + - oas3 + message: "Response documents MUST follow application/hal+json schema: {{error}}" + then: + field: schema + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/HAL.yaml" + + + # --------------------------------------------------------------------------- + # Not implemented + # --------------------------------------------------------------------------- + + # --------------------------------------------------------------------------- + # Other rules which are redundant or not feasible + # --------------------------------------------------------------------------- + + # fields-date-iso8601: + # description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html) + # severity: error + # fields-language-iso639: + # description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html) + # severity: error + # fields-country-iso3166: + # description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + # severity: error + # fields-currency-iso4217: + # description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217) + # severity: error + # response-303-async-link-header: + # description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header + # severity: hint