├── img ├── .gitignore ├── logo.png └── api-process.png ├── .gitignore ├── api-process.md ├── spectral ├── tests │ ├── asyncapi │ │ ├── testData │ │ │ ├── info-without-contact.yaml │ │ │ ├── info-with-contact-invalid.yaml │ │ │ ├── spec-with-info-ref-invalid.yaml │ │ │ ├── info-with-contact-valid.yaml │ │ │ ├── info-with-contact-x-team-id-valid.yaml │ │ │ └── spec-with-info-ref-x-team-id-valid.yaml │ │ └── async-schema.test.ts │ ├── openapi │ │ ├── testData │ │ │ ├── info-without-contact-invalid.yaml │ │ │ ├── allOf-element-2.yaml │ │ │ ├── allOf-element-1.yaml │ │ │ ├── paths-without-tag.yaml │ │ │ ├── allOf-element-inconsistent.yaml │ │ │ ├── paths-without-security.yaml │ │ │ ├── paths-without-summary.yaml │ │ │ ├── paths-with-summary.yaml │ │ │ ├── paths-with-tag.yaml │ │ │ ├── paths-with-security.yaml │ │ │ ├── oas3ApiServers │ │ │ │ ├── external-servers-valid.yaml │ │ │ │ ├── external-servers-non-empty.yaml │ │ │ │ ├── external-servers-multiple.yaml │ │ │ │ ├── spec-with-external-servers-missing.yaml │ │ │ │ ├── spec-with-external-servers-valid.yaml │ │ │ │ ├── spec-with-external-servers-broken-ref.yaml │ │ │ │ ├── spec-with-external-servers-non-empty.yaml │ │ │ │ └── spec-with-external-servers-multiple.yaml │ │ │ ├── info-with-contact-id-invalid.yaml │ │ │ ├── info-with-contact-name-invalid.yaml │ │ │ ├── info-with-contact-id-valid.yaml │ │ │ ├── oas3ParameterDescription │ │ │ │ ├── external-operation-parameters-without-description.yaml │ │ │ │ ├── external-path-parameters-without-description.yaml │ │ │ │ ├── external-component-parameters-without-description.yaml │ │ │ │ ├── external-path-parameters-with-description.yaml │ │ │ │ ├── external-operation-parameters-with-description.yaml │ │ │ │ ├── external-component-parameters-with-description.yaml │ │ │ │ ├── spec-with-external-path-parameters-with-description.yaml │ │ │ │ ├── spec-with-external-operation-parameters-with-description.yaml │ │ │ │ ├── spec-with-external-path-parameters-without-description.yaml │ │ │ │ ├── spec-with-external-operation-parameters-without-description.yaml │ │ │ │ ├── spec-with-external-component-parameters-with-description.yaml │ │ │ │ └── spec-with-external-component-parameters-without-description.yaml │ │ │ ├── info-with-contact-name-valid.yaml │ │ │ ├── oas3ExamplesValueOrExternalValue │ │ │ │ ├── external-example-invalid.yaml │ │ │ │ ├── external-example-valid.yaml │ │ │ │ ├── spec-with-external-ref-valid-example.yaml │ │ │ │ └── spec-with-external-ref-invalid-example.yaml │ │ │ ├── oas3ServerTrailingSlash │ │ │ │ ├── external-server-with-trailing-slash.yaml │ │ │ │ ├── external-server-without-trailing-slash.yaml │ │ │ │ ├── spec-with-external-server-trailing-slash.yaml │ │ │ │ └── spec-with-external-server-no-trailing-slash.yaml │ │ │ ├── enum-valid.yaml │ │ │ ├── objectRequestResponsePostfix │ │ │ │ ├── user-schemas-invalid-request.yaml │ │ │ │ ├── user-schemas-valid-request.yaml │ │ │ │ ├── response-invalid.yaml │ │ │ │ ├── request-body-invalid.yaml │ │ │ │ ├── request-body-valid.yaml │ │ │ │ ├── response-valid.yaml │ │ │ │ ├── response-schema-ref-invalid.yaml │ │ │ │ ├── response-ref-invalid.yaml │ │ │ │ ├── response-ref-valid.yaml │ │ │ │ ├── request-body-ref-invalid.yaml │ │ │ │ ├── schema-ref-invalid-request.yaml │ │ │ │ └── schema-ref-valid-request.yaml │ │ │ ├── operation-must-have-tag-spec-with-ref.yaml │ │ │ ├── operationTagDefined │ │ │ │ ├── path-with-valid-tag.yaml │ │ │ │ ├── path-with-invalid-tag.yaml │ │ │ │ ├── spec-with-external-path-ref-valid.yaml │ │ │ │ └── spec-with-external-path-ref-invalid.yaml │ │ │ ├── operation-must-have-tag-spec-with-ref-valid.yaml │ │ │ ├── operationSingularTag │ │ │ │ ├── path-with-single-tag.yaml │ │ │ │ ├── path-with-multiple-tags.yaml │ │ │ │ ├── spec-with-external-path-ref-single.yaml │ │ │ │ └── spec-with-external-path-ref-multiple.yaml │ │ │ ├── enum-invalid.yaml │ │ │ ├── operation-must-have-security-spec-with-ref.yaml │ │ │ ├── operation-must-have-summary-spec-with-ref-valid.yaml │ │ │ ├── operation-must-have-summary-spec-with-ref.yaml │ │ │ ├── oas3OperationSecurityDefined │ │ │ │ ├── external-security-schemes.yaml │ │ │ │ ├── spec-with-external-security-schemes-ref.yaml │ │ │ │ └── spec-with-external-security-schemes-ref-invalid.yaml │ │ │ ├── operation-must-have-security-spec-with-ref-valid.yaml │ │ │ ├── ref-head-method-spec.yaml │ │ │ ├── path-params │ │ │ │ ├── path-with-invalid-params.yaml │ │ │ │ ├── path-params-external-valid.yaml │ │ │ │ ├── path-params-external-invalid.yaml │ │ │ │ ├── path-with-valid-params.yaml │ │ │ │ └── ref-with-invalid-path-params.yaml │ │ │ ├── oas3ServerVariables │ │ │ │ ├── external-servers-invalid-url.yaml │ │ │ │ ├── spec-with-external-servers-valid.yaml │ │ │ │ ├── spec-with-external-servers-invalid-url.yaml │ │ │ │ ├── spec-with-external-servers-invalid.yaml │ │ │ │ ├── spec-with-external-servers-invalid-default.yaml │ │ │ │ ├── external-servers-invalid-default.yaml │ │ │ │ ├── external-servers-invalid-missing-variables.yaml │ │ │ │ ├── spec-with-external-servers-multiple-valid.yaml │ │ │ │ ├── external-servers-valid.yaml │ │ │ │ └── external-servers-multiple-valid.yaml │ │ │ ├── queryParams │ │ │ │ ├── ref-query-params-spec.yaml │ │ │ │ ├── query-params-camel-case-spec-external-valid.yaml │ │ │ │ ├── query-params-camel-case-spec-external-invalid.yaml │ │ │ │ ├── query-params-camel-case-valid-ref.yaml │ │ │ │ ├── query-params-camel-case-invalid-ref.yaml │ │ │ │ └── ref-query-params.yaml │ │ │ ├── method-operation-id-camel-case-spec-with-ref-valid.yaml │ │ │ ├── method-request-response-components-spec-with-path-ref.yaml │ │ │ ├── no-eval-in-markdown-spec-ref-error.yaml │ │ │ ├── oas3ValidMediaExample │ │ │ │ ├── external-schema-invalid.yaml │ │ │ │ ├── external-schema-valid.yaml │ │ │ │ ├── spec-with-external-valid-example.yaml │ │ │ │ └── spec-with-external-invalid-example.yaml │ │ │ ├── method-operation-id-camel-case-spec-with-ref-invalid.yaml │ │ │ ├── enum-discriminator-upper-snake-case-spec-with-ref-valid.yaml │ │ │ ├── external-bad-model.yaml │ │ │ ├── operationSuccessResponse │ │ │ │ ├── path-with-success-response.yaml │ │ │ │ ├── spec-with-external-path-ref-success.yaml │ │ │ │ ├── spec-with-external-path-ref-no-success.yaml │ │ │ │ └── path-with-no-success-response.yaml │ │ │ ├── enum-discriminator-upper-snake-case-spec-with-ref-invalid.yaml │ │ │ ├── oas31CallbacksInWebhook │ │ │ │ ├── webhook-with-external-ref.yaml │ │ │ │ ├── webhook-with-external-ref-no-callbacks.yaml │ │ │ │ ├── external-webhook-no-callbacks.yaml │ │ │ │ └── external-webhook.yaml │ │ │ ├── method-request-response-components-spec-with-path-ref-errors.yaml │ │ │ ├── validSchemaExample │ │ │ │ ├── external-model-without-example.yaml │ │ │ │ ├── external-model-with-partial-example.yaml │ │ │ │ ├── external-model-with-example.yaml │ │ │ │ ├── spec-with-external-model-with-example.yaml │ │ │ │ ├── spec-with-external-model-without-example.yaml │ │ │ │ ├── spec-with-external-model-with-partial-example.yaml │ │ │ │ ├── complex-external-model-without-examples.yaml │ │ │ │ └── spec-with-complex-external-model-without-examples.yaml │ │ │ ├── operationParameters │ │ │ │ ├── spec-with-external-path-ref-unique.yaml │ │ │ │ ├── spec-with-external-path-ref-duplicate.yaml │ │ │ │ ├── path-with-unique-parameters.yaml │ │ │ │ └── path-with-duplicate-parameters.yaml │ │ │ ├── components-without-descriptions.yaml │ │ │ ├── methodRequestResponseComponents │ │ │ │ ├── method-operation-id-camel-case-spec-with-ref-valid.yaml │ │ │ │ ├── method-request-response-components-spec-with-path-ref.yaml │ │ │ │ ├── method-operation-id-camel-case-spec-with-ref-invalid.yaml │ │ │ │ ├── method-request-response-components-spec-with-path-ref-errors.yaml │ │ │ │ ├── method-request-response-components-spec-with-external-schema-refs.yaml │ │ │ │ ├── operation-invalid.yaml │ │ │ │ ├── operation-valid.yaml │ │ │ │ ├── user-schemas.yaml │ │ │ │ ├── external-request-body-components.yaml │ │ │ │ ├── external-response-components.yaml │ │ │ │ ├── two-level-deep-schemas.yaml │ │ │ │ ├── path-with-external-schema-refs.yaml │ │ │ │ ├── path-with-inline-schemas.yaml │ │ │ │ ├── method-request-response-components-spec-with-external-response-ref.yaml │ │ │ │ ├── ref.yaml │ │ │ │ ├── method-request-response-components-spec-with-external-request-body-ref.yaml │ │ │ │ ├── path-with-schemas-2-level-deep.yaml │ │ │ │ ├── method-request-response-components-spec-with-mixed-paths.yaml │ │ │ │ ├── method-request-response-components-2-level-deep.yaml │ │ │ │ └── ref-test-spec.yaml │ │ │ ├── spec-with-info-ref-id-valid.yaml │ │ │ ├── operationDescription │ │ │ │ ├── spec-with-external-path-ref-with-description.yaml │ │ │ │ ├── spec-with-external-path-ref-missing-description.yaml │ │ │ │ ├── path-with-external-ref-missing-description.yaml │ │ │ │ ├── ref.yaml │ │ │ │ ├── path-with-external-ref-with-description.yaml │ │ │ │ └── ref-test-spec.yaml │ │ │ ├── operationOperationId │ │ │ │ ├── spec-with-external-path-ref-with-operationId.yaml │ │ │ │ ├── spec-with-external-path-ref-missing-operationId.yaml │ │ │ │ ├── path-with-external-ref-missing-operationId.yaml │ │ │ │ ├── ref.yaml │ │ │ │ ├── path-with-external-ref-with-operationId.yaml │ │ │ │ └── ref-test-spec.yaml │ │ │ ├── spec-with-info-ref-id-invalid.yaml │ │ │ ├── enum-discriminator-upper-snake-case-spec-with-ref-discriminator-valid.yaml │ │ │ ├── method-request-response-components-spec-with-external-schema-refs.yaml │ │ │ ├── operationOperationIdValidInUrl │ │ │ │ ├── spec-with-external-path-ref-valid.yaml │ │ │ │ ├── spec-with-external-path-ref-invalid.yaml │ │ │ │ ├── path-with-valid-operationId.yaml │ │ │ │ └── path-with-invalid-operationId.yaml │ │ │ ├── enum-discriminator-upper-snake-case-spec-with-ref-discriminator-invalid.yaml │ │ │ ├── noScriptTags │ │ │ │ ├── external-ref-model-without-script.yaml │ │ │ │ ├── external-ref-model-with-script.yaml │ │ │ │ ├── no-script-tags-in-markdown-spec-external-error.yaml │ │ │ │ ├── no-script-tags-in-markdown-spec-external-valid.yaml │ │ │ │ ├── no-script-tags-in-markdown-spec-valid.yaml │ │ │ │ └── no-script-tags-in-markdown-spec-error.yaml │ │ │ ├── operation-valid.yaml │ │ │ ├── operation-invalid.yaml │ │ │ ├── useMostCommonHttpCodes │ │ │ │ ├── spec-with-external-ref-to-allowed-codes.yaml │ │ │ │ ├── spec-with-external-ref-to-disallowed-codes.yaml │ │ │ │ ├── external-spec-with-allowed-codes.yaml │ │ │ │ └── external-spec-with-disallowed-codes.yaml │ │ │ ├── user-schemas.yaml │ │ │ ├── notUseRedirectionCodes │ │ │ │ ├── spec-with-external-ref-to-redirection-codes.yaml │ │ │ │ ├── spec-with-external-ref-to-valid-codes.yaml │ │ │ │ ├── external-spec-without-redirection-codes.yaml │ │ │ │ └── external-spec-with-redirection-codes.yaml │ │ │ ├── components-with-descriptions.yaml │ │ │ ├── oas3ValidSchemaExample │ │ │ │ ├── external-schema-with-valid-example.yaml │ │ │ │ ├── external-schema-with-invalid-example.yaml │ │ │ │ ├── spec-with-direct-external-schema-valid-example.yaml │ │ │ │ └── spec-with-direct-external-schema-invalid-example.yaml │ │ │ ├── noRefSiblings │ │ │ │ ├── external-ref-model.yaml │ │ │ │ ├── no-ref-siblings-spec-external-error.yaml │ │ │ │ ├── no-ref-siblings-spec-external-valid.yaml │ │ │ │ ├── no-ref-siblings-spec-valid.yaml │ │ │ │ └── no-ref-siblings-spec-error.yaml │ │ │ ├── typedEnum │ │ │ │ ├── typed-enum-external-error.yaml │ │ │ │ ├── typed-enum-external-valid.yaml │ │ │ │ ├── typed-enum-spec-with-external-ref-error.yaml │ │ │ │ └── typed-enum-spec-with-external-ref-valid.yaml │ │ │ ├── ref-head-method.yaml │ │ │ ├── oas3CallbacksInCallbacks │ │ │ │ ├── external-path-without-nested-callbacks.yaml │ │ │ │ ├── spec-with-external-ref-nested-callbacks.yaml │ │ │ │ ├── spec-with-external-ref-no-nested-callbacks.yaml │ │ │ │ └── external-path-with-nested-callbacks.yaml │ │ │ ├── operationOperationIdUnique │ │ │ │ ├── external-path-with-operation-id.yaml │ │ │ │ ├── spec-with-external-path-ref.yaml │ │ │ │ └── spec-with-external-path-ref-duplicate.yaml │ │ │ ├── discriminator-valid.yaml │ │ │ ├── oas3UnusedComponent │ │ │ │ ├── external-components-unused.yaml │ │ │ │ ├── external-components-used.yaml │ │ │ │ ├── spec-with-external-unused-components.yaml │ │ │ │ └── spec-with-external-used-components.yaml │ │ │ ├── names-should-be-in-english-external-spec.yaml │ │ │ ├── names-should-be-in-english-valid-external-spec.yaml │ │ │ ├── external-good-model.yaml │ │ │ ├── no-eval-in-markdown-with-ref.yaml │ │ │ ├── ref-with-invalid-tags.yaml │ │ │ ├── discriminator-invalid.yaml │ │ │ ├── external-blank-strings-schema.yaml │ │ │ ├── external-body-fields-valid-model.yaml │ │ │ ├── external-body-fields-model.yaml │ │ │ ├── oas31ServersInWebhook │ │ │ │ ├── spec-with-external-webhook-ref-servers-operation-level.yaml │ │ │ │ └── external-webhook-with-servers-operation-level.yaml │ │ │ ├── description-required-for-schema-fields-spec-with-ref-valid.yaml │ │ │ ├── description-required-for-schema-fields-spec-with-ref.yaml │ │ │ ├── spec-with-external-allOf-elements.yaml │ │ │ ├── spec-with-external-blank-strings.yaml │ │ │ ├── spec-with-external-body-fields.yaml │ │ │ ├── method-request-response-components-spec-with-external-response-ref.yaml │ │ │ ├── method-request-response-components-spec-with-external-request-body-ref.yaml │ │ │ ├── spec-with-external-body-fields-valid.yaml │ │ │ ├── path-with-external-ref-correct.yaml │ │ │ ├── oas3_callbacks_in_callbacks-valid.yaml │ │ │ ├── ref.yaml │ │ │ ├── spec-with-external-bad-model.yaml │ │ │ ├── spec-with-external-good-model.yaml │ │ │ ├── spec-with-external-allOf-inconsistent.yaml │ │ │ ├── method-request-response-components-spec-with-mixed-paths.yaml │ │ │ ├── method-request-response-components-2-level-deep.yaml │ │ │ ├── oas3_callbacks_in_callbacks-invalid.yaml │ │ │ ├── names-should-be-in-english-spec-not-valid.yaml │ │ │ ├── names-should-be-in-english-english-spec-valid.yaml │ │ │ ├── duplicated-entry-in-enum-spec-error.yaml │ │ │ ├── duplicated-entry-in-enum-spec-valid.yaml │ │ │ ├── ref-test-spec.yaml │ │ │ └── no-eval-in-markdown-spec-error.yaml │ │ └── duplicated-entry-in-enum.test.ts │ ├── utils │ │ ├── severity.ts │ │ └── utils.ts │ └── common │ │ └── testData │ │ ├── asyncapi │ │ ├── external-ref-forbidden-spec-error.yaml │ │ ├── external-ref-forbidden-spec-error-additional.yaml │ │ ├── external-ref-forbidden-spec-valid.yaml │ │ ├── external-ref-forbidden-spec-servers-ref.yaml │ │ └── external-ref-forbidden-spec-internal-blocks.yaml │ │ └── openapi │ │ ├── external-ref-forbidden-spec-error-additional.yaml │ │ ├── ref.yaml │ │ ├── external-ref-forbidden-spec-error.yaml │ │ ├── external-ref-forbidden-spec-valid.yaml │ │ └── ref-test-spec.yaml ├── tsconfig.json ├── .husky │ └── pre-commit ├── rules │ ├── asyncapi │ │ └── required │ │ │ ├── async-schema.yaml │ │ │ ├── contact-x-team-id-required.yaml │ │ │ └── supported-schema-version.yaml │ ├── openapi │ │ ├── oas3-schema.yaml │ │ ├── operation-must-have-summary.yaml │ │ ├── info-contact.yaml │ │ ├── description-required-for-schema-fields.yaml │ │ ├── tag-description.yaml │ │ ├── info-description.yaml │ │ ├── openapi-tags.yaml │ │ ├── oas3-1-callbacks-in-webhook.yaml │ │ ├── operation-operationId.yaml │ │ ├── no-eval-in-markdown.yaml │ │ ├── oas3-1-servers-in-webhook.yaml │ │ ├── operation-must-have-tag.yaml │ │ ├── typed-enum.yaml │ │ ├── path-not-include-query.yaml │ │ ├── path-params.yaml │ │ ├── operation-operationId-unique.yaml │ │ ├── operation-tag-defined.yaml │ │ ├── path-keys-no-trailing-slash.yaml │ │ ├── no-script-tags-in-markdown.yaml │ │ ├── operation-description.yaml │ │ ├── no-ref-siblings.yaml │ │ ├── oas3-server-trailing-slash.yaml │ │ ├── openapi-tags-alphabetical.yaml │ │ ├── openapi-tags-uniqueness.yaml │ │ ├── provide-head-method.yaml │ │ ├── contact-x-team-id-required.yaml │ │ ├── oas3-callbacks-in-callbacks.yaml │ │ ├── url-versioning.yaml │ │ ├── all-off-types-consistency.yaml │ │ ├── path-declarations-must-exist.yaml │ │ ├── path-no-redundant-prefixes.yaml │ │ ├── empty-objects-forbidden.yaml │ │ ├── oas3-unused-component.yaml │ │ ├── path-kebab-case.yaml │ │ ├── method-operation-id-camel-case.yaml │ │ ├── operation-must-have-security.yaml │ │ ├── not-use-redirection-codes.yaml │ │ ├── duplicated-entry-in-enum.yaml │ │ ├── valid-schema-example.yaml │ │ ├── method-request-response-components.yaml │ │ ├── query-params-camel-case.yaml │ │ ├── supported-schema-version.yaml │ │ ├── use-most-common-http-codes.yaml │ │ ├── object-request-response-postfix.yaml │ │ ├── oas3-api-servers.yaml │ │ ├── operation-singular-tag.yaml │ │ ├── operation-parameters.yaml │ │ ├── operation-success-response.yaml │ │ ├── enum-discriminator-upper-snake-case.yaml │ │ ├── operation-operationId-valid-in-url.yaml │ │ ├── oas3-parameter-description.yaml │ │ ├── blank-strings-forbidden.yaml │ │ ├── oas3-examples-value-or-externalValue.yaml │ │ ├── array-items.yaml │ │ ├── oas3-valid-media-example.yaml │ │ ├── body-fields-camel-case.yaml │ │ ├── oas3-operation-security-defined.yaml │ │ ├── names-should-be-in-english.yaml │ │ ├── oas3-server-variables.yaml │ │ └── oas3-valid-schema-example.yaml │ └── common │ │ ├── external-ref-forbidden.yaml │ │ └── README.md ├── functions │ ├── utils │ │ ├── isObject.js │ │ ├── replaceString.js │ │ └── getAllOperations.js │ ├── operationMustHaveSecurity.js │ ├── arrayItems.js │ ├── oasOpSuccessResponse.js │ ├── allOffTypesConsistency.js │ └── oasTagDefined.js ├── eslint.config.js ├── required-ruleset.yaml └── asyncapi-required-ruleset.yaml ├── examples └── README.md ├── use-cases └── README.md ├── сontributing └── VERSIONING.md └── rules └── rule-format.md /img/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/node_modules/ 3 | **/junit.xml 4 | /.idea -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Raiffeisen-DGTL/rest-api-guide/HEAD/img/logo.png -------------------------------------------------------------------------------- /api-process.md: -------------------------------------------------------------------------------- 1 | 2 | ![Diagram](img/api-process.png) 3 | [Source](img/src/api-process.drawio) 4 | -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/info-without-contact.yaml: -------------------------------------------------------------------------------- 1 | title: Test Spec 2 | version: '0.0.1' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/info-without-contact-invalid.yaml: -------------------------------------------------------------------------------- 1 | title: Test Spec 2 | version: 0.0.2 -------------------------------------------------------------------------------- /spectral/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /img/api-process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Raiffeisen-DGTL/rest-api-guide/HEAD/img/api-process.png -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/allOf-element-2.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | properties: 3 | id: 4 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/allOf-element-1.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | properties: 3 | name: 4 | type: string -------------------------------------------------------------------------------- /spectral/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Generate rulesets 4 | cd "$(dirname "$0")/.." && node build-rulesets.js 5 | -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-without-tag.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | responses: 3 | '200': 4 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/allOf-element-inconsistent.yaml: -------------------------------------------------------------------------------- 1 | type: string 2 | properties: 3 | id: 4 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-without-security.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | responses: 3 | '200': 4 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-without-summary.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | responses: 3 | '200': 4 | description: Success -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/info-with-contact-invalid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | name: Test Team 3 | title: Test Spec 4 | version: '0.0.1' -------------------------------------------------------------------------------- /spectral/rules/asyncapi/required/async-schema.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ required ] 2 | extends: [[spectral:asyncapi, off]] 3 | rules: 4 | asyncapi-schema: error -------------------------------------------------------------------------------- /spectral/rules/openapi/oas3-schema.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ required, base, documentation ] 2 | extends: [[spectral:oas, off]] 3 | rules: 4 | oas3-schema: error -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/spec-with-info-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | asyncapi: '2.0.0' 2 | info: 3 | $ref: './info-with-contact-invalid.yaml' 4 | channels: {} -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-with-summary.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | summary: Get test resource 3 | responses: 4 | '200': 5 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-with-tag.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | tags: 3 | - Test Resource 4 | responses: 5 | '200': 6 | description: Success -------------------------------------------------------------------------------- /spectral/tests/utils/severity.ts: -------------------------------------------------------------------------------- 1 | export const enum Severity { 2 | error = 0, 3 | warning = 1, 4 | info = 2, 5 | hint = 3, 6 | off = -1, 7 | } 8 | -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/info-with-contact-valid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | name: Test Team 3 | x-short-team-name: TT 4 | title: Test Spec 5 | version: '0.0.1' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/paths-with-security.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | security: 3 | - api_key: [ ] 4 | responses: 5 | '200': 6 | description: Success -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/info-with-contact-x-team-id-valid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | name: Test Team 3 | x-team-id: 198 4 | title: Test Spec 5 | version: '0.0.1' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/external-servers-valid.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/v1' 3 | description: 'Production server' -------------------------------------------------------------------------------- /spectral/tests/asyncapi/testData/spec-with-info-ref-x-team-id-valid.yaml: -------------------------------------------------------------------------------- 1 | asyncapi: '2.0.0' 2 | info: 3 | $ref: './info-with-contact-x-team-id-valid.yaml' 4 | channels: {} -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/external-servers-non-empty.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/v1' 3 | description: 'Production server' -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Реальные кейсы команд банка 2 | 3 | ### Практика API First | Демонстрация от команды CDC Integrations - 22.05.2025 4 | https://train.raiffeisen.ru/node/30305 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/info-with-contact-id-invalid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | url: https://sometestserver.ru/198 3 | name: Test Team 4 | title: Test Spec 5 | version: 0.0.2 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/info-with-contact-name-invalid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | url: https://sometestserver.ru/198 3 | name: Test Team 4 | title: Test Spec 5 | version: 0.0.2 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/info-with-contact-id-valid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | url: https://sometestserver.ru/198 3 | name: Test Team 4 | x-team-id: 198 5 | title: Test Spec 6 | version: 0.0.2 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-operation-parameters-without-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: limit 3 | in: query 4 | schema: 5 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/info-with-contact-name-valid.yaml: -------------------------------------------------------------------------------- 1 | contact: 2 | url: https://sometestserver.ru/198 3 | name: Test Team 4 | x-short-team-name: 198 5 | title: Test Spec 6 | version: 0.0.2 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ExamplesValueOrExternalValue/external-example-invalid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | examples: 3 | ExternalExample: 4 | summary: 'Example without value or externalValue' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerTrailingSlash/external-server-with-trailing-slash.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/' 3 | description: 'Production server with trailing slash' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerTrailingSlash/external-server-without-trailing-slash.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com' 3 | description: 'Production server without trailing slash' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-valid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | Status: 4 | type: string 5 | enum: 6 | - NEW_ORDER 7 | - CANCELLED 8 | - EXPIRED 9 | - PAID -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-path-parameters-without-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: id 3 | in: path 4 | required: true 5 | schema: 6 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/user-schemas-invalid-request.yaml: -------------------------------------------------------------------------------- 1 | UserCreate: 2 | type: object 3 | properties: 4 | name: 5 | type: string 6 | email: 7 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-tag-spec-with-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-without-tag.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationTagDefined/path-with-valid-tag.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | tags: ['test'] 3 | summary: Test operation 4 | operationId: 'getTest' 5 | responses: 6 | '200': 7 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/user-schemas-valid-request.yaml: -------------------------------------------------------------------------------- 1 | UserCreateRequest: 2 | type: object 3 | properties: 4 | name: 5 | type: string 6 | email: 7 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-tag-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-with-tag.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSingularTag/path-with-single-tag.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | tags: ['test'] 3 | summary: Test operation 4 | operationId: 'getTest' 5 | responses: 6 | '200': 7 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-invalid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | Status: 4 | type: string 5 | enum: 6 | - NewOrder 7 | - cancelled 8 | - expired-order 9 | - PAID -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-security-spec-with-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-without-security.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-summary-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-with-summary.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-summary-spec-with-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-without-summary.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3OperationSecurityDefined/external-security-schemes.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | securitySchemes: 3 | external_api_key: 4 | type: apiKey 5 | in: header 6 | name: X-External-API-Key -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-component-parameters-without-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | UserId: 3 | name: id 4 | in: path 5 | required: true 6 | schema: 7 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-must-have-security-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './paths-with-security.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationTagDefined/path-with-invalid-tag.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | tags: ['undefined-tag'] 3 | summary: Test operation 4 | operationId: 'getTest' 5 | responses: 6 | '200': 7 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/ref-head-method-spec.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Ref for HEAD Method 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './ref-head-method.yaml#/paths/~1download' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSingularTag/path-with-multiple-tags.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | tags: ['test', 'production'] 3 | summary: Test operation 4 | operationId: 'getTest' 5 | responses: 6 | '200': 7 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/path-params/path-with-invalid-params.yaml: -------------------------------------------------------------------------------- 1 | paths: 2 | /users/{id}: 3 | get: 4 | # Missing path parameter definition for {id} 5 | responses: 6 | '200': 7 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-path-parameters-with-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: id 3 | in: path 4 | description: User ID 5 | required: true 6 | schema: 7 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ExamplesValueOrExternalValue/external-example-valid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | examples: 3 | ExternalExample: 4 | summary: 'Example with value' 5 | value: 6 | id: 1 7 | name: 'Test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-operation-parameters-with-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: limit 3 | in: query 4 | description: Number of users to return 5 | schema: 6 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/external-servers-invalid-url.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com:{port}/v1' 3 | description: 'Production server' 4 | variables: 5 | port: 6 | default: '8o80' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/ref-query-params-spec.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Ref for Query Params 4 | version: 0.0.1 5 | paths: 6 | /test-ref: 7 | $ref: './ref-query-params.yaml#/paths/~1test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/method-operation-id-camel-case-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Valid OperationId 4 | version: 0.0.1 5 | paths: 6 | /v1/api/test: 7 | $ref: './operation-valid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/method-request-response-components-spec-with-path-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-inline-schemas.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/no-eval-in-markdown-spec-ref-error.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Invalid OperationId 4 | version: 0.0.1 5 | paths: 6 | /v1/api/test: 7 | $ref: './no-eval-in-markdown-with-ref.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/external-servers-multiple.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/v1' 3 | description: 'Production server' 4 | - url: 'https://api-staging.example.com/v1' 5 | description: 'Staging server' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/spec-with-external-servers-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Valid Servers 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-servers-valid.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidMediaExample/external-schema-invalid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidMediaExample/external-schema-valid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/method-operation-id-camel-case-spec-with-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Invalid OperationId 4 | version: 0.0.1 5 | paths: 6 | /v1/api/test: 7 | $ref: './operation-invalid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/external-component-parameters-with-description.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | UserId: 3 | name: id 4 | in: path 5 | description: User ID 6 | required: true 7 | schema: 8 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-discriminator-upper-snake-case-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Valid Enum 4 | version: 0.0.1 5 | components: 6 | schemas: 7 | Status: 8 | $ref: './enum-valid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/external-bad-model.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TheBadModel: 4 | type: object 5 | properties: 6 | favoriteColorSets: 7 | type: array 8 | # Missing items field - this should trigger the rule -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/spec-with-external-servers-invalid-url.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Servers Invalid URL 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-servers-invalid-url.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSuccessResponse/path-with-success-response.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getUsers 3 | summary: Get users 4 | responses: 5 | '200': 6 | description: Successful response 7 | '400': 8 | description: Bad request -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/path-params/path-params-external-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path Ref - Valid 4 | version: 0.0.1 5 | paths: 6 | /users/{id}: 7 | $ref: './path-with-valid-params.yaml#/paths/~1users~1{id}' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-discriminator-upper-snake-case-spec-with-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Invalid Enum 4 | version: 0.0.1 5 | components: 6 | schemas: 7 | Status: 8 | $ref: './enum-invalid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas31CallbacksInWebhook/webhook-with-external-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.1.0 2 | info: 3 | title: Test Spec with External Webhook Ref 4 | version: 0.0.1 5 | webhooks: 6 | myWebhook: 7 | $ref: './external-webhook.yaml#/webhooks/externalWebhook' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSingularTag/spec-with-external-path-ref-single.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Single Tag 4 | version: 0.0.2 5 | paths: 6 | /v1/api/test: 7 | $ref: './path-with-single-tag.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/path-params/path-params-external-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path Ref - Invalid 4 | version: 0.0.1 5 | paths: 6 | /users/{id}: 7 | $ref: './path-with-invalid-params.yaml#/paths/~1users~1{id}' -------------------------------------------------------------------------------- /use-cases/README.md: -------------------------------------------------------------------------------- 1 | # Use Cases - руководства для специфических типов API: 2 | 3 | 4 | - Файловое API (upload/download) 5 | - Асинхронное API (async tasks, webhooks) 6 | - Batch операции 7 | - GraphQL в банке 8 | - Event-driven API 9 | 10 | > ...будет наполняться -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/method-request-response-components-spec-with-path-ref-errors.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref and Inline Schemas 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-inline-schemas.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/spec-with-external-servers-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Invalid Servers 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-servers-invalid-missing-variables.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/query-params-camel-case-spec-external-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref Valid 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './query-params-camel-case-valid-ref.yaml#/paths/~1users' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/external-model-without-example.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | ExternalModelWithoutExample: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/spec-with-external-servers-invalid-default.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Servers Invalid Default 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-servers-invalid-default.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationParameters/spec-with-external-path-ref-unique.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Unique Parameters 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './path-with-unique-parameters.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSingularTag/spec-with-external-path-ref-multiple.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Multiple Tags 4 | version: 0.0.2 5 | paths: 6 | /v1/api/test: 7 | $ref: './path-with-multiple-tags.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/query-params-camel-case-spec-external-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref Invalid 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './query-params-camel-case-invalid-ref.yaml#/paths/~1users' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/components-without-descriptions.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string 10 | description: User name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/method-operation-id-camel-case-spec-with-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Valid OperationId 4 | version: 0.0.1 5 | paths: 6 | /v1/api/test: 7 | $ref: './operation-valid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/method-request-response-components-spec-with-path-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-inline-schemas.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerTrailingSlash/spec-with-external-server-trailing-slash.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Server with Trailing Slash 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-server-with-trailing-slash.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSuccessResponse/spec-with-external-path-ref-success.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Success Response 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './path-with-success-response.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/spec-with-info-ref-id-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | $ref: './info-with-contact-id-valid.yaml' 4 | servers: 5 | - description: test 6 | url: https://test.sometestserver.ru/ 7 | - description: prod 8 | url: https://prod.sometestserver.ru/ -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/method-operation-id-camel-case-spec-with-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Invalid OperationId 4 | version: 0.0.1 5 | paths: 6 | /v1/api/test: 7 | $ref: './operation-invalid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/external-servers-invalid-default.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/{region}' 3 | description: 'Production server' 4 | variables: 5 | region: 6 | default: 'us-south' 7 | enum: ['us-west', 'us-east'] -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationDescription/spec-with-external-path-ref-with-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with External Path Ref With Description 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-ref-with-description.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationId/spec-with-external-path-ref-with-operationId.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with External Path Ref With OperationId 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-ref-with-operationId.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationParameters/spec-with-external-path-ref-duplicate.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Duplicate Parameters 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './path-with-duplicate-parameters.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/spec-with-info-ref-id-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | $ref: './info-with-contact-id-invalid.yaml' 4 | servers: 5 | - description: test 6 | url: https://test.sometestserver.ru/ 7 | - description: prod 8 | url: https://prod.sometestserver.ru/ -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-discriminator-upper-snake-case-spec-with-ref-discriminator-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Valid Discriminator 4 | version: 0.0.1 5 | components: 6 | schemas: 7 | Payment: 8 | $ref: './discriminator-valid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/method-request-response-components-spec-with-external-schema-refs.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref and External Schema Refs 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-schema-refs.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerTrailingSlash/spec-with-external-server-no-trailing-slash.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Server without Trailing Slash 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-server-without-trailing-slash.yaml#/servers/0' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/external-servers-invalid-missing-variables.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.example.com/{region}' 3 | description: 'Production server' 4 | variables: 5 | version: 6 | default: 'v1' 7 | description: 'API version' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdValidInUrl/spec-with-external-path-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Valid OperationId 4 | version: 0.0.2 5 | paths: 6 | /v1/api/test: 7 | $ref: './path-with-valid-operationId.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSuccessResponse/spec-with-external-path-ref-no-success.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - No Success Response 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './path-with-no-success-response.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/enum-discriminator-upper-snake-case-spec-with-ref-discriminator-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Refs for Invalid Discriminator 4 | version: 0.0.1 5 | components: 6 | schemas: 7 | Payment: 8 | $ref: './discriminator-invalid.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noScriptTags/external-ref-model-without-script.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string 10 | description: A user name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationDescription/spec-with-external-path-ref-missing-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with External Path Ref Missing Description 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-ref-missing-description.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationId/spec-with-external-path-ref-missing-operationId.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with External Path Ref Missing OperationId 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-ref-missing-operationId.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdValidInUrl/spec-with-external-path-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Invalid OperationId 4 | version: 0.0.2 5 | paths: 6 | /v1/api/test: 7 | $ref: './path-with-invalid-operationId.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-valid.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getTest 3 | summary: Test endpoint 4 | responses: 5 | '200': 6 | description: OK 7 | post: 8 | operationId: createUser 9 | summary: Create user 10 | responses: 11 | '201': 12 | description: Created -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/method-request-response-components-spec-with-path-ref-errors.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref and Inline Schemas 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-inline-schemas.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas31CallbacksInWebhook/webhook-with-external-ref-no-callbacks.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.1.0 2 | info: 3 | title: Test Spec with External Webhook Ref No Callbacks 4 | version: 0.0.1 5 | webhooks: 6 | myWebhook: 7 | $ref: './external-webhook-no-callbacks.yaml#/webhooks/externalWebhook' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operation-invalid.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: get_test 3 | summary: Test endpoint 4 | responses: 5 | '200': 6 | description: OK 7 | post: 8 | operationId: create_user 9 | summary: Create user 10 | responses: 11 | '201': 12 | description: Created -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/useMostCommonHttpCodes/spec-with-external-ref-to-allowed-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Spec with External Reference to File with Allowed HTTP Codes 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './external-spec-with-allowed-codes.yaml#/paths/~1external-test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/user-schemas.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: { type: 'integer' } 7 | name: { type: 'string' } 8 | UserInput: 9 | type: object 10 | properties: 11 | name: { type: 'string' } -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/notUseRedirectionCodes/spec-with-external-ref-to-redirection-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Spec with External Reference to File with Redirection Codes 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './external-spec-with-redirection-codes.yaml#/paths/~1external-test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/notUseRedirectionCodes/spec-with-external-ref-to-valid-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Spec with External Reference to File without Redirection Codes 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './external-spec-without-redirection-codes.yaml#/paths/~1external-test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/components-with-descriptions.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | description: User identifier 9 | name: 10 | type: string 11 | description: User name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/method-request-response-components-spec-with-external-schema-refs.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test Spec with Path as External Ref and External Schema Refs 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | $ref: './path-with-external-schema-refs.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/spec-with-external-servers-missing.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test API with External Servers Referenced But Missing Servers Array 4 | version: 1.0.0 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: 'OK' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationSuccessResponse/path-with-no-success-response.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getUsers 3 | summary: Get users 4 | responses: 5 | '400': 6 | description: Bad request 7 | '404': 8 | description: Not found 9 | '500': 10 | description: Internal server error -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/useMostCommonHttpCodes/spec-with-external-ref-to-disallowed-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Spec with External Reference to File with Disallowed HTTP Codes 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | $ref: './external-spec-with-disallowed-codes.yaml#/paths/~1external-test' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidSchemaExample/external-schema-with-valid-example.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | example: 123 9 | name: 10 | type: string 11 | example: "John Doe" -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationTagDefined/spec-with-external-path-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Valid Tag 4 | version: 0.0.2 5 | tags: 6 | - name: test 7 | description: Test tag 8 | paths: 9 | /v1/api/test: 10 | $ref: './path-with-valid-tag.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/path-params/path-with-valid-params.yaml: -------------------------------------------------------------------------------- 1 | paths: 2 | /users/{id}: 3 | get: 4 | parameters: 5 | - name: id 6 | in: path 7 | required: true 8 | schema: 9 | type: string 10 | responses: 11 | '200': 12 | description: OK -------------------------------------------------------------------------------- /spectral/tests/common/testData/asyncapi/external-ref-forbidden-spec-error.yaml: -------------------------------------------------------------------------------- 1 | asyncapi: '2.0.0' 2 | info: 3 | title: Test Spec with External Ref 4 | version: '0.0.1' 5 | channels: 6 | test.channel: 7 | subscribe: 8 | message: 9 | $ref: '/external-ref-forbidden-spec-error-additional.yaml#/components/schemas/TheGoodModel' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/operation-invalid.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: get_test 3 | summary: Test endpoint 4 | responses: 5 | '200': 6 | description: OK 7 | post: 8 | operationId: create_user 9 | summary: Create user 10 | responses: 11 | '201': 12 | description: Created -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/operation-valid.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getTest 3 | summary: Test endpoint 4 | responses: 5 | '200': 6 | description: OK 7 | post: 8 | operationId: createUser 9 | summary: Create user 10 | responses: 11 | '201': 12 | description: Created -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/spec-with-external-servers-multiple-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Servers Multiple Valid 4 | version: 0.0.1 5 | servers: 6 | - $ref: './external-servers-multiple-valid.yaml#/servers/0' 7 | - $ref: './external-servers-multiple-valid.yaml#/servers/1' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/user-schemas.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: { type: 'integer' } 7 | name: { type: 'string' } 8 | UserInput: 9 | type: object 10 | properties: 11 | name: { type: 'string' } -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noRefSiblings/external-ref-model.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | $ref: '#/components/schemas/User2' 5 | description: 'description' 6 | User2: 7 | type: object 8 | properties: 9 | id: 10 | type: integer 11 | name: 12 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationTagDefined/spec-with-external-path-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Invalid Tag 4 | version: 0.0.2 5 | tags: 6 | - name: test 7 | description: Test tag 8 | paths: 9 | /v1/api/test: 10 | $ref: './path-with-invalid-tag.yaml' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/typedEnum/typed-enum-external-error.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | StatusModel: 4 | type: object 5 | properties: 6 | status: 7 | type: string 8 | enum: 9 | - active 10 | - inactive 11 | - 1 # This should fail the typed-enum rule -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/typedEnum/typed-enum-external-valid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | StatusModel: 4 | type: object 5 | properties: 6 | status: 7 | type: string 8 | enum: 9 | - active 10 | - inactive 11 | - pending # This should pass the typed-enum rule -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noScriptTags/external-ref-model-with-script.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | description: User ID 9 | name: 10 | type: string 11 | description: A user name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/spec-with-external-servers-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test API with External Valid Servers 4 | version: 1.0.0 5 | servers: 6 | - $ref: './external-servers-valid.yaml#/servers/0' 7 | paths: 8 | /users: 9 | get: 10 | responses: 11 | '200': 12 | description: 'OK' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/useMostCommonHttpCodes/external-spec-with-allowed-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: External Spec with Allowed HTTP Codes 4 | version: 0.0.1 5 | paths: 6 | /external-test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | '404': 12 | description: Not Found -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/notUseRedirectionCodes/external-spec-without-redirection-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: External Spec without Redirection Codes 4 | version: 0.0.1 5 | paths: 6 | /external-test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | '404': 12 | description: Not Found -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/spec-with-external-servers-broken-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test API with Non-Existent External Reference 4 | version: 1.0.0 5 | servers: 6 | - $ref: './non-existent-file.yaml#/servers/0' 7 | paths: 8 | /users: 9 | get: 10 | responses: 11 | '200': 12 | description: 'OK' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/spec-with-external-servers-non-empty.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test API with External Non-Empty Servers 4 | version: 1.0.0 5 | servers: 6 | - $ref: './external-servers-non-empty.yaml#/servers/0' 7 | paths: 8 | /users: 9 | get: 10 | responses: 11 | '200': 12 | description: 'OK' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/ref-head-method.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec for HEAD Method Ref 4 | version: 0.0.1 5 | paths: 6 | /download: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/pdf: {} 13 | # Missing HEAD method - should trigger the rule -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/notUseRedirectionCodes/external-spec-with-redirection-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: External Spec with Redirection Codes 4 | version: 0.0.1 5 | paths: 6 | /external-test: 7 | get: 8 | responses: 9 | '301': 10 | description: Moved Permanently 11 | '302': 12 | description: Found -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidSchemaExample/external-schema-with-invalid-example.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | example: "not-an-integer" # This should trigger an error 9 | name: 10 | type: string 11 | example: "John Doe" -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/response-invalid.yaml: -------------------------------------------------------------------------------- 1 | UserCreate: 2 | description: Success 3 | content: 4 | application/json: 5 | schema: 6 | type: object 7 | properties: 8 | id: 9 | type: string 10 | name: 11 | type: string 12 | email: 13 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ServerVariables/external-servers-valid.yaml: -------------------------------------------------------------------------------- 1 | servers: 2 | - url: 'https://api.{region}.example.com/{version}' 3 | description: 'Production server' 4 | variables: 5 | version: 6 | default: 'v1' 7 | description: 'API version' 8 | region: 9 | default: 'us-east' 10 | enum: ['us-west', 'us-east'] -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/useMostCommonHttpCodes/external-spec-with-disallowed-codes.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: External Spec with Disallowed HTTP Codes 4 | version: 0.0.1 5 | paths: 6 | /external-test: 7 | get: 8 | responses: 9 | '207': 10 | description: Multi-status 11 | '418': 12 | description: I'm a teapot -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/external-model-with-partial-example.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | ExternalModelWithPartialExample: 4 | type: object 5 | example: 6 | id: 123 7 | properties: 8 | id: 9 | type: integer 10 | example: 123 11 | name: 12 | type: string 13 | # Missing example here -------------------------------------------------------------------------------- /spectral/rules/openapi/operation-must-have-summary.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | operation-must-have-summary: 4 | description: 'Каждая операция должна содержать поле summary' 5 | severity: error 6 | given: '$.paths[*][?(@property.match(/^(get|put|post|delete|patch|options|head|trace)$/))]' 7 | then: 8 | - field: summary 9 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3CallbacksInCallbacks/external-path-without-nested-callbacks.yaml: -------------------------------------------------------------------------------- 1 | callbackContent: 2 | post: 3 | requestBody: 4 | content: 5 | application/json: 6 | schema: 7 | type: object 8 | properties: 9 | id: 10 | type: string 11 | responses: 12 | '200': 13 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/request-body-invalid.yaml: -------------------------------------------------------------------------------- 1 | UserCreate: 2 | content: 3 | application/json: 4 | schema: 5 | $ref: '#/components/schemas/UserRequest' 6 | components: 7 | schemas: 8 | UserRequest: 9 | type: object 10 | properties: 11 | name: 12 | type: string 13 | email: 14 | type: string -------------------------------------------------------------------------------- /spectral/tests/common/testData/asyncapi/external-ref-forbidden-spec-error-additional.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TheGoodModel: 4 | type: object 5 | properties: 6 | number_of_connectors: 7 | type: integer 8 | description: The number of extension points. 9 | enum: 10 | - 1 11 | - 2 12 | - 4 13 | - 5 -------------------------------------------------------------------------------- /spectral/tests/common/testData/openapi/external-ref-forbidden-spec-error-additional.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TheGoodModel: 4 | type: object 5 | properties: 6 | number_of_connectors: 7 | type: integer 8 | description: The number of extension points. 9 | enum: 10 | - 1 11 | - 2 12 | - 4 13 | - 5 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/request-body-valid.yaml: -------------------------------------------------------------------------------- 1 | UserCreateRequest: 2 | content: 3 | application/json: 4 | schema: 5 | $ref: '#/components/schemas/UserRequest' 6 | components: 7 | schemas: 8 | UserRequest: 9 | type: object 10 | properties: 11 | name: 12 | type: string 13 | email: 14 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdUnique/external-path-with-operation-id.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getUsers 3 | responses: 4 | '200': 5 | description: Success 6 | content: 7 | 'application/json': 8 | schema: 9 | type: object 10 | properties: 11 | id: { type: 'integer' } 12 | name: { type: 'string' } -------------------------------------------------------------------------------- /spectral/functions/utils/isObject.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Проверяет, является ли значение объектом (и не null, и не массивом). 5 | * 6 | * @param {*} value — любое значение 7 | * @returns {boolean} — true, если значение является объектом 8 | */ 9 | function isObject(value) { 10 | return value !== null && typeof value === 'object' && !Array.isArray(value) 11 | } 12 | export { isObject } 13 | -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdUnique/spec-with-external-path-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './external-path-with-operation-id.yaml' 8 | /v1/posts: 9 | get: 10 | operationId: getPosts 11 | responses: 12 | '200': 13 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/external-model-with-example.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | ExternalModelWithExample: 4 | type: object 5 | example: 6 | id: 123 7 | name: "Test Name" 8 | properties: 9 | id: 10 | type: integer 11 | example: 123 12 | name: 13 | type: string 14 | example: "Test Name" -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas31CallbacksInWebhook/external-webhook-no-callbacks.yaml: -------------------------------------------------------------------------------- 1 | webhooks: 2 | externalWebhook: 3 | post: 4 | requestBody: 5 | content: 6 | 'application/json': 7 | schema: 8 | type: object 9 | properties: 10 | id: { type: 'string' } 11 | responses: 12 | '200': 13 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdValidInUrl/path-with-valid-operationId.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getTestOperation 3 | responses: 4 | '200': 5 | description: Success 6 | content: 7 | 'application/json': 8 | schema: 9 | type: object 10 | properties: 11 | id: { type: 'integer' } 12 | name: { type: 'string' } -------------------------------------------------------------------------------- /spectral/rules/openapi/info-contact.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation ] 2 | rules: 3 | info-contact: 4 | description: Блок info должен содержать раздел contact 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#info-contact 6 | severity: error 7 | given: '$' 8 | then: 9 | field: 'info.contact' 10 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/discriminator-valid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | Payment: 4 | type: object 5 | discriminator: 6 | propertyName: paymentType 7 | mapping: 8 | CREDIT_CARD: '#/components/schemas/CreditCardPayment' 9 | BANK_TRANSFER: '#/components/schemas/BankTransferPayment' 10 | properties: 11 | paymentType: 12 | type: string -------------------------------------------------------------------------------- /spectral/rules/openapi/description-required-for-schema-fields.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | description-required-for-schema-fields: 4 | description: 'У каждого поля в схеме должен быть description' 5 | severity: error 6 | given: 7 | - '$..properties.*' 8 | - '$.components.schemas.*.enum[*]' 9 | then: 10 | - field: 'description' 11 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ApiServers/spec-with-external-servers-multiple.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test API with External Multiple Servers 4 | version: 1.0.0 5 | servers: 6 | - $ref: './external-servers-multiple.yaml#/servers/0' 7 | - $ref: './external-servers-multiple.yaml#/servers/1' 8 | paths: 9 | /users: 10 | get: 11 | responses: 12 | '200': 13 | description: 'OK' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3UnusedComponent/external-components-unused.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | ExternalUser: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string 10 | ExternalUnusedUser: 11 | type: object 12 | properties: 13 | id: 14 | type: integer 15 | name: 16 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3UnusedComponent/external-components-used.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | ExternalUser: 4 | type: object 5 | properties: 6 | id: 7 | type: integer 8 | name: 9 | type: string 10 | ExternalAddress: 11 | type: object 12 | properties: 13 | street: 14 | type: string 15 | city: 16 | type: string -------------------------------------------------------------------------------- /spectral/tests/common/testData/asyncapi/external-ref-forbidden-spec-valid.yaml: -------------------------------------------------------------------------------- 1 | asyncapi: '2.0.0' 2 | info: 3 | title: Test Spec with Internal Ref 4 | version: '0.0.1' 5 | channels: 6 | test.channel: 7 | subscribe: 8 | message: 9 | $ref: '#/components/schemas/TestModel' 10 | components: 11 | schemas: 12 | TestModel: 13 | type: object 14 | properties: 15 | id: 16 | type: string -------------------------------------------------------------------------------- /spectral/rules/openapi/tag-description.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | tag-description: 4 | description: Блок tags должен содержать description 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#tag-description 6 | severity: warn 7 | given: '$.tags[*]' 8 | then: 9 | field: 'description' 10 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/names-should-be-in-english-external-spec.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | пользователь: # English name 4 | type: object 5 | properties: 6 | имя: # English name 7 | type: string 8 | фамилия: # English name 9 | type: string 10 | Status: 11 | type: string 12 | enum: 13 | - активный 14 | - неактивный 15 | - pending -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/names-should-be-in-english-valid-external-spec.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | User: # English name 4 | type: object 5 | properties: 6 | firstName: # English name 7 | type: string 8 | lastName: # English name 9 | type: string 10 | Status: 11 | type: string 12 | enum: 13 | - active 14 | - inactive 15 | - pending -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdValidInUrl/path-with-invalid-operationId.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: "getTest Operation" # Invalid due to space 3 | responses: 4 | '200': 5 | description: Success 6 | content: 7 | 'application/json': 8 | schema: 9 | type: object 10 | properties: 11 | id: { type: 'integer' } 12 | name: { type: 'string' } -------------------------------------------------------------------------------- /spectral/rules/openapi/info-description.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | info-description: 4 | description: Блок info должен содержать раздел description 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#info-description 6 | severity: error 7 | given: '$' 8 | then: 9 | field: 'info.description' 10 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationParameters/path-with-unique-parameters.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getUsers 3 | summary: Get users 4 | parameters: 5 | - name: userId 6 | in: path 7 | required: true 8 | schema: 9 | type: string 10 | - name: limit 11 | in: query 12 | required: false 13 | schema: 14 | type: integer 15 | responses: 16 | '200': 17 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationParameters/path-with-duplicate-parameters.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: getUsers 3 | summary: Get users 4 | parameters: 5 | - name: userId 6 | in: path 7 | required: true 8 | schema: 9 | type: string 10 | - name: userId 11 | in: path 12 | required: false 13 | schema: 14 | type: integer 15 | responses: 16 | '200': 17 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/query-params-camel-case-valid-ref.yaml: -------------------------------------------------------------------------------- 1 | paths: 2 | /users: 3 | get: 4 | parameters: 5 | - name: userId 6 | in: query 7 | schema: 8 | type: string 9 | - name: firstName 10 | in: query 11 | schema: 12 | type: string 13 | - name: pageSize 14 | in: query 15 | schema: 16 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/typedEnum/typed-enum-spec-with-external-ref-error.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test API with External Ref 4 | version: 1.0.0 5 | paths: 6 | /test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/json: 13 | schema: 14 | $ref: './typed-enum-external-error.yaml#/components/schemas/StatusModel' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/typedEnum/typed-enum-spec-with-external-ref-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Test API with External Ref 4 | version: 1.0.0 5 | paths: 6 | /test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/json: 13 | schema: 14 | $ref: './typed-enum-external-valid.yaml#/components/schemas/StatusModel' -------------------------------------------------------------------------------- /spectral/rules/openapi/openapi-tags.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | openapi-tags: 4 | description: Массив tags не должен быть пустым 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#openapi-tags 6 | severity: error 7 | given: '$' 8 | then: 9 | field: 'tags' 10 | function: length 11 | functionOptions: 12 | min: 1 -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/external-request-body-components.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | requestBodies: 3 | UserCreateBody: 4 | content: 5 | application/json: 6 | schema: 7 | $ref: '#/components/schemas/UserCreate' 8 | schemas: 9 | UserCreate: 10 | type: object 11 | properties: 12 | name: 13 | type: string 14 | email: 15 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noRefSiblings/no-ref-siblings-spec-external-error.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref Error 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: Success 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-ref-model.yaml#/components/schemas/User' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/query-params-camel-case-invalid-ref.yaml: -------------------------------------------------------------------------------- 1 | paths: 2 | /users: 3 | get: 4 | parameters: 5 | - name: user_id 6 | in: query 7 | schema: 8 | type: string 9 | - name: first_name 10 | in: query 11 | schema: 12 | type: string 13 | - name: page_size 14 | in: query 15 | schema: 16 | type: integer -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ExamplesValueOrExternalValue/spec-with-external-ref-valid-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref containing valid examples 4 | version: 0.0.1 5 | components: 6 | examples: 7 | LocalExample: 8 | $ref: './external-example-valid.yaml#/components/examples/ExternalExample' 9 | paths: 10 | /test: 11 | get: 12 | responses: 13 | '200': 14 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/external-good-model.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TheGoodModel: 4 | type: object 5 | properties: 6 | favoriteColorSets: 7 | type: array 8 | items: 9 | type: string 10 | name: 11 | type: string 12 | description: Valid description 13 | title: 14 | type: string 15 | title: Valid title 16 | required: 17 | - name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/external-response-components.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | responses: 3 | UserCreatedResponse: 4 | description: Created 5 | content: 6 | application/json: 7 | schema: 8 | $ref: '#/components/schemas/User' 9 | schemas: 10 | User: 11 | type: object 12 | properties: 13 | id: 14 | type: integer 15 | name: 16 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/no-eval-in-markdown-with-ref.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | operationId: get_test 3 | description: 'some description with eval("alert(\"You are Hacked\");")' 4 | summary: Test endpoint 5 | responses: 6 | '200': 7 | description: OK 8 | post: 9 | operationId: create_user 10 | summary: Create user 11 | description: 'some description with eval("alert(\"You are Hacked\");")' 12 | responses: 13 | '201': 14 | description: Created -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ExamplesValueOrExternalValue/spec-with-external-ref-invalid-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref containing invalid examples 4 | version: 0.0.1 5 | components: 6 | examples: 7 | LocalExample: 8 | $ref: './external-example-invalid.yaml#/components/examples/ExternalExample' 9 | paths: 10 | /test: 11 | get: 12 | responses: 13 | '200': 14 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/objectRequestResponsePostfix/response-valid.yaml: -------------------------------------------------------------------------------- 1 | UserCreateResponse: 2 | description: Success 3 | content: 4 | application/json: 5 | schema: 6 | $ref: '#/components/schemas/UserResponse' 7 | components: 8 | schemas: 9 | UserResponse: 10 | type: object 11 | properties: 12 | id: 13 | type: string 14 | name: 15 | type: string 16 | email: 17 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noScriptTags/no-script-tags-in-markdown-spec-external-error.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref Error 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: Success 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-ref-model-with-script.yaml#/components/schemas/User' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/noScriptTags/no-script-tags-in-markdown-spec-external-valid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref Valid 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: Success 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-ref-model-without-script.yaml#/components/schemas/User' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/ref-with-invalid-tags.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Invalid Tags Ref 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | get: 8 | tags: ['undefined-tag'] # This tag is not defined in global tags 9 | responses: 10 | '200': 11 | description: OK 12 | content: 13 | application/json: 14 | schema: 15 | $ref: './ref.yaml#/components/schemas/TestModel' -------------------------------------------------------------------------------- /spectral/rules/openapi/oas3-1-callbacks-in-webhook.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation ] 2 | rules: 3 | oas3_1-callbacks-in-webhook: 4 | description: Webhooks не должны включать в себя callbacks 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#oas3_1-callbacks-in-webhook 6 | severity: error 7 | formats: [oas3_1] 8 | given: '$.webhooks[*][*].callbacks' 9 | then: 10 | function: undefined -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3OperationSecurityDefined/spec-with-external-security-schemes-ref.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Security Schemes Ref 4 | version: 0.0.1 5 | components: 6 | securitySchemes: 7 | $ref: './external-security-schemes.yaml#/components/securitySchemes' 8 | paths: 9 | /test: 10 | get: 11 | security: 12 | - external_api_key: [] 13 | responses: 14 | '200': 15 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/queryParams/ref-query-params.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec for Query Params Ref 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | get: 8 | parameters: 9 | - name: user_id # This should fail the rule 10 | in: query 11 | schema: 12 | type: string 13 | - name: first_name # This should also fail the rule 14 | in: query 15 | schema: 16 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/discriminator-invalid.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | Payment: 4 | type: object 5 | discriminator: 6 | propertyName: paymentType 7 | mapping: 8 | credit-card: '#/components/schemas/CreditCardPayment' 9 | BANK_TRANSFER: '#/components/schemas/BankTransferPayment' 10 | BankTransfer: '#/components/schemas/BankTransferPayment' 11 | properties: 12 | paymentType: 13 | type: string -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/spec-with-external-path-parameters-with-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path Parameters with Description 4 | version: 0.0.1 5 | paths: 6 | /users/{id}: 7 | get: 8 | summary: Get user by ID 9 | parameters: 10 | - $ref: './external-path-parameters-with-description.yaml#/parameters/0' 11 | responses: 12 | '200': 13 | description: User object -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/operationOperationIdUnique/spec-with-external-path-ref-duplicate.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path References - Duplicate OperationId 4 | version: 0.0.2 5 | paths: 6 | /v1/users: 7 | $ref: './external-path-with-operation-id.yaml' 8 | /v1/posts: 9 | get: 10 | operationId: getUsers # Same operationId as in the external reference 11 | responses: 12 | '200': 13 | description: Success -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/spec-with-external-model-with-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Model With Example 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/json: 13 | schema: 14 | $ref: './external-model-with-example.yaml#/components/schemas/ExternalModelWithExample' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3CallbacksInCallbacks/spec-with-external-ref-nested-callbacks.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref containing nested callbacks 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | post: 8 | callbacks: 9 | myCallback: 10 | 'https://example.com/callback': 11 | $ref: './external-path-with-nested-callbacks.yaml#/callbackContent' 12 | responses: 13 | '200': 14 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/spec-with-external-operation-parameters-with-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Operation Parameters with Description 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | summary: Get users 9 | parameters: 10 | - $ref: './external-operation-parameters-with-description.yaml#/parameters/0' 11 | responses: 12 | '200': 13 | description: List of users -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/spec-with-external-path-parameters-without-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Path Parameters without Description 4 | version: 0.0.1 5 | paths: 6 | /users/{id}: 7 | get: 8 | summary: Get user by ID 9 | parameters: 10 | - $ref: './external-path-parameters-without-description.yaml#/parameters/0' 11 | responses: 12 | '200': 13 | description: User object -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/path-params/ref-with-invalid-path-params.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Invalid Path Params Ref 4 | version: 0.0.1 5 | paths: 6 | /users/{id}: 7 | get: 8 | # Missing path parameter definition for {id} 9 | responses: 10 | '200': 11 | description: OK 12 | content: 13 | application/json: 14 | schema: 15 | $ref: '../ref.yaml#/components/schemas/TestModel' -------------------------------------------------------------------------------- /spectral/rules/openapi/operation-operationId.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | operation-operationId: 4 | description: Каждый path должен иметь operationId 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#operation-operationId 6 | severity: error 7 | given: '$.paths[*][get,put,post,delete,options,head,patch,trace]' 8 | then: 9 | field: 'operationId' 10 | function: truthy -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/external-blank-strings-schema.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TestModel: 4 | type: object 5 | properties: 6 | description: 7 | type: string 8 | description: " " # Blank string in description 9 | example: " " # Blank string in example 10 | title: 11 | type: string 12 | title: " " # Blank string in title 13 | required: 14 | - " " # Blank string in required array -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/two-level-deep-schemas.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | TheGoodModel: 4 | type: object 5 | properties: 6 | favoriteColorSets: 7 | type: array 8 | items: 9 | type: string 10 | name: 11 | type: string 12 | description: Valid description 13 | title: 14 | type: string 15 | title: Valid title 16 | required: 17 | - name -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3CallbacksInCallbacks/spec-with-external-ref-no-nested-callbacks.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Ref without nested callbacks 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | post: 8 | callbacks: 9 | myCallback: 10 | 'https://example.com/callback': 11 | $ref: './external-path-without-nested-callbacks.yaml#/callbackContent' 12 | responses: 13 | '200': 14 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/spec-with-external-model-without-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Model Without Example 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/json: 13 | schema: 14 | $ref: './external-model-without-example.yaml#/components/schemas/ExternalModelWithoutExample' -------------------------------------------------------------------------------- /spectral/rules/openapi/no-eval-in-markdown.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | no-eval-in-markdown: 4 | description: Блок description и title не должен содержать eval() 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#no-eval-in-markdown 6 | severity: error 7 | given: '$..[description,title]' 8 | then: 9 | function: pattern 10 | functionOptions: 11 | notMatch: "eval\\(" -------------------------------------------------------------------------------- /spectral/rules/openapi/oas3-1-servers-in-webhook.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation ] 2 | rules: 3 | oas3-1-servers-in-webhook: 4 | description: Webhooks не должны включать в себя servers 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#oas3_1-servers-in-webhook 6 | severity: error 7 | formats: [ oas3_1 ] 8 | given: [ '$.webhooks.servers', '$.webhooks[*][*].servers' ] 9 | then: 10 | function: undefined -------------------------------------------------------------------------------- /spectral/rules/openapi/operation-must-have-tag.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | operation-must-have-tag: 4 | description: 'Каждая операция (endpoint) должна быть снабжена тегом' 5 | severity: warn 6 | given: '$.paths[*][?(@property.match(/^(get|put|post|delete|patch|options|head|trace)$/))]' 7 | then: 8 | - field: tags 9 | function: truthy 10 | - field: tags 11 | function: length 12 | functionOptions: 13 | min: 1 -------------------------------------------------------------------------------- /spectral/rules/openapi/typed-enum.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | functions: 3 | - typedEnum 4 | functionsDir: "../../functions" 5 | rules: 6 | typed-enum: 7 | description: Каждый элемент Enum должен соответствовать указанному типу 8 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#typed-enum 9 | severity: error 10 | given: '$..[?(@ && @.enum && @.type)]' 11 | then: 12 | function: typedEnum -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ParameterDescription/spec-with-external-operation-parameters-without-description.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Operation Parameters without Description 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | summary: Get users 9 | parameters: 10 | - $ref: './external-operation-parameters-without-description.yaml#/parameters/0' 11 | responses: 12 | '200': 13 | description: List of users -------------------------------------------------------------------------------- /spectral/rules/openapi/path-not-include-query.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | path-not-include-query: 4 | description: Path не должен содержать символов "?" 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#path-not-include-query 6 | severity: error 7 | given: '$.paths' 8 | then: 9 | field: '@key' 10 | function: pattern 11 | functionOptions: 12 | notMatch: '\?.+' -------------------------------------------------------------------------------- /spectral/rules/openapi/path-params.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | functions: 3 | - oasPathParam 4 | functionsDir: "../../functions" 5 | rules: 6 | path-params: 7 | description: Параметры пути должны быть описаны и использованы 8 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#path-params 9 | severity: error 10 | resolved: false 11 | given: '$.paths' 12 | then: 13 | function: oasPathParam -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3OperationSecurityDefined/spec-with-external-security-schemes-ref-invalid.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Security Schemes Ref - Invalid 4 | version: 0.0.1 5 | components: 6 | securitySchemes: 7 | $ref: './external-security-schemes.yaml#/components/securitySchemes' 8 | paths: 9 | /test: 10 | get: 11 | security: 12 | - invalid_external_scheme: [] 13 | responses: 14 | '200': 15 | description: OK -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidSchemaExample/spec-with-direct-external-schema-valid-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Direct External Schema Reference Valid Example 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-schema-with-valid-example.yaml#/components/schemas/User' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/methodRequestResponseComponents/path-with-external-schema-refs.yaml: -------------------------------------------------------------------------------- 1 | get: 2 | responses: 3 | '200': 4 | description: Success 5 | content: 6 | 'application/json': 7 | schema: 8 | $ref: './user-schemas.yaml#/components/schemas/User' 9 | '400': 10 | description: Bad request 11 | requestBody: 12 | content: 13 | 'application/json': 14 | schema: 15 | $ref: './user-schemas.yaml#/components/schemas/UserInput' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3UnusedComponent/spec-with-external-unused-components.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Unused Components 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-components-unused.yaml#/components/schemas/ExternalUser' 15 | components: 16 | schemas: {} -------------------------------------------------------------------------------- /spectral/rules/common/external-ref-forbidden.yaml: -------------------------------------------------------------------------------- 1 | rules: 2 | external-ref-forbidden: 3 | description: "Все $ref должны ссылаться на components" 4 | message: Найдена ссылка на внешний компонент {{value}} 5 | severity: error 6 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#external-ref-forbidden 7 | given: "$..$ref" 8 | resolved: false 9 | then: 10 | function: pattern 11 | functionOptions: 12 | match: "^#/" -------------------------------------------------------------------------------- /spectral/rules/openapi/operation-operationId-unique.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | functions: 3 | - oasOpIdUnique 4 | functionsDir: "../../functions" 5 | rules: 6 | operation-operationId-unique: 7 | description: OperationId должен быть уникальным 8 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#operation-operationId-unique 9 | severity: error 10 | given: '$.paths' 11 | then: 12 | function: oasOpIdUnique -------------------------------------------------------------------------------- /spectral/rules/openapi/operation-tag-defined.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | functions: 3 | - oasTagDefined 4 | functionsDir: "../../functions" 5 | rules: 6 | operation-tag-defined: 7 | description: Tags методов должны быть определены в глобальном списке tags 8 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#operation-tag-defined 9 | severity: error 10 | given: '$' 11 | then: 12 | function: oasTagDefined -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/oas3ValidSchemaExample/spec-with-direct-external-schema-invalid-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with Direct External Schema Reference Invalid Example 4 | version: 0.0.1 5 | paths: 6 | /users: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | 'application/json': 13 | schema: 14 | $ref: './external-schema-with-invalid-example.yaml#/components/schemas/User' -------------------------------------------------------------------------------- /spectral/tests/openapi/testData/validSchemaExample/spec-with-external-model-with-partial-example.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Test Spec with External Model With Partial Example 4 | version: 0.0.1 5 | paths: 6 | /test: 7 | get: 8 | responses: 9 | '200': 10 | description: OK 11 | content: 12 | application/json: 13 | schema: 14 | $ref: './external-model-with-partial-example.yaml#/components/schemas/ExternalModelWithPartialExample' -------------------------------------------------------------------------------- /spectral/rules/openapi/path-keys-no-trailing-slash.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | path-keys-no-trailing-slash: 4 | description: Path не должен заканчиваться на символ / 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#path-keys-no-trailing-slash 6 | severity: info 7 | given: '$.paths' 8 | then: 9 | field: '@key' 10 | function: pattern 11 | functionOptions: 12 | notMatch: './$' -------------------------------------------------------------------------------- /spectral/rules/asyncapi/required/contact-x-team-id-required.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ required ] 2 | rules: 3 | contact-x-team-id-required: 4 | description: Поле info.contact.x-team-id является обязательным 5 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/asyncapi?ref_type=heads#contact-x-team-id-required 6 | message: Отсутствует поле info.contact.x-team-id 7 | severity: error 8 | given: $.info 9 | then: 10 | field: contact.x-team-id 11 | function: truthy -------------------------------------------------------------------------------- /spectral/rules/openapi/no-script-tags-in-markdown.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | rules: 3 | no-script-tags-in-markdown: 4 | description: Блок description и title не должен содержать ' 6 | version: 0.0.2 7 | servers: 8 | - description: 'some description with ' 9 | url: https://test.sometestserver.ru/ 10 | - description: 'some description with ' 11 | url: https://prod.sometestserver.ru/ 12 | paths: 13 | /v1/api/test: 14 | get: 15 | tags: 16 | - testing endpoint 17 | summary: Для тестирования правил 18 | operationId: getTest 19 | responses: 20 | '200': 21 | description: 'some description with ' 22 | content: 23 | application/json: 24 | schema: 25 | $ref: '#/components/schemas/TheGoodModel' 26 | components: 27 | schemas: 28 | TheGoodModel: 29 | type: object 30 | properties: 31 | number_of_connectors: 32 | type: integer 33 | description: The number of extension points. 34 | enum: 35 | - 1 36 | - 2 37 | - 4 38 | - 5 39 | -------------------------------------------------------------------------------- /spectral/functions/arrayItems.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import { createRulesetFunction } from '@stoplight/spectral-core' 3 | 4 | const seenTargets = new WeakSet() 5 | 6 | export default createRulesetFunction( 7 | { 8 | input: { 9 | type: 'object', 10 | }, 11 | options: null, 12 | }, 13 | function arrayItems(targetVal) { 14 | if (targetVal == null || typeof targetVal !== 'object') { 15 | return 16 | } 17 | 18 | // Если уже проверяли этот объект (например, после резолва $ref), больше не проверяем 19 | if (seenTargets.has(targetVal)) { 20 | return 21 | } 22 | seenTargets.add(targetVal) 23 | 24 | // Проверяем тип array (включая 3.1, где type может быть массивом) 25 | const { type } = targetVal 26 | const isArrayType = type === 'array' || (Array.isArray(type) && type.includes('array')) 27 | 28 | if (!isArrayType) { 29 | return 30 | } 31 | 32 | // Проверяем, что есть хотя бы один из допустимых ключей для элементов 33 | const hasItems = Object.prototype.hasOwnProperty.call(targetVal, 'items') 34 | const hasPrefixItems = Object.prototype.hasOwnProperty.call(targetVal, 'prefixItems') 35 | 36 | if (!hasItems && !hasPrefixItems) { 37 | return [ 38 | { 39 | message: 'Объекты типа Array должны содержать массив элементов', 40 | }, 41 | ] 42 | } 43 | }, 44 | ) 45 | -------------------------------------------------------------------------------- /spectral/rules/openapi/oas3-valid-schema-example.yaml: -------------------------------------------------------------------------------- 1 | x-rulesets: [ base, documentation, ai-ready ] 2 | functions: 3 | - oasExample 4 | functionsDir: "../../functions" 5 | rules: 6 | oas3-valid-schema-example: 7 | description: Examples в описании схемы должны соответствовать объявленным типам 8 | documentationUrl: https://gitlabci.raiffeisen.ru/cib/api-guide/-/tree/master/spectral/rules/openapi?ref_type=heads#oas3-valid-schema-example 9 | formats: [ oas3_0 ] 10 | severity: error 11 | given: 12 | - "$.components.schemas..[?(@property !== 'properties' && @ && (@ && @.example !== void 0 || @.default !== void 0) && (@.enum || @.type || @.format || @.$ref || @.properties || @.items))]" 13 | - "$..content..[?(@property !== 'properties' && @ && (@ && @.example !== void 0 || @.default !== void 0) && (@.enum || @.type || @.format || @.$ref || @.properties || @.items))]" 14 | - "$..headers..[?(@property !== 'properties' && @ && (@ && @.example !== void 0 || @.default !== void 0) && (@.enum || @.type || @.format || @.$ref || @.properties || @.items))]" 15 | - "$..parameters..[?(@property !== 'properties' && @ && (@ && @.example !== void 0 || @.default !== void 0) && (@.enum || @.type || @.format || @.$ref || @.properties || @.items))]" 16 | then: 17 | function: oasExample 18 | functionOptions: 19 | schemaField: '$' 20 | oasVersion: 3 21 | type: 'schema' -------------------------------------------------------------------------------- /spectral/functions/oasOpSuccessResponse.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import { createRulesetFunction } from '@stoplight/spectral-core' 3 | import { oas3 } from '@stoplight/spectral-formats' 4 | // import { oas3_0 as oas3 } from './utils/format'; 5 | 6 | export default createRulesetFunction( 7 | { 8 | // Входной параметр - это объект (обычно `responses` секция у операции) 9 | input: { 10 | type: 'object', 11 | }, 12 | options: null, 13 | }, 14 | function oasOpSuccessResponse(input, opts, context) { 15 | // Определяем, что документ действительно OpenAPI 3.x 16 | const isOAS3X = context.document.formats?.has(oas3) === true 17 | 18 | // Перебираем все ключи ответов 19 | for (const response of Object.keys(input)) { 20 | // Для OpenAPI 3.x разрешены обобщённые "2XX" и "3XX" 21 | if (isOAS3X && (response === '2XX' || response === '3XX')) { 22 | return // всё ок — есть успешный ответ 23 | } 24 | 25 | // Если статус‑код от 200 до 399 включительно — это успешный ответ 26 | const code = Number(response) 27 | if (!isNaN(code) && code >= 200 && code < 400) { 28 | return // есть успешный ответ, ошибки нет 29 | } 30 | } 31 | 32 | // Если не найдено ни одного успешного кода — возвращаем ошибку проверки 33 | return [ 34 | { 35 | message: 'Operation must define at least a single 2xx or 3xx response', 36 | }, 37 | ] 38 | }, 39 | ) 40 | -------------------------------------------------------------------------------- /spectral/rules/common/README.md: -------------------------------------------------------------------------------- 1 | - [Common](#common) 2 | - [external-ref-forbidden](#external-ref-forbidden) 3 | 4 | ## Common 5 | 6 | ### external-ref-forbidden 7 | 8 | | Severity | Description | 9 | |----------|-----------------------------------------| 10 | | ERROR | Все $ref должны ссылаться не должны ссылнать на внешние файлы | 11 | 12 | #### Описание 13 | 14 | Правило проверяет наличие внешних ссылок в спецификации 15 | 16 | #### Решение 17 | 18 | ```textmate 19 | Проверьте все $ref в вашей спецификации и убедитесь, что все они ведут в эту же спецификацию 20 | ``` 21 | 22 | #### Примеры 23 | 24 | ##### Правильно 25 | ```yaml 26 | components: 27 | schemas: 28 | User: 29 | type: object 30 | properties: 31 | name: 32 | type: string 33 | age: 34 | type: integer 35 | Address: 36 | type: object 37 | properties: 38 | street: 39 | type: string 40 | paths: 41 | /users: 42 | get: 43 | responses: 44 | '200': 45 | content: 46 | application/json: 47 | schema: 48 | $ref: '#/components/schemas/User' 49 | ``` 50 | 51 | ##### Неправильно 52 | ```yaml 53 | paths: 54 | /users: 55 | get: 56 | responses: 57 | '200': 58 | content: 59 | application/json: 60 | schema: 61 | $ref: 'https://example.com/api.yaml#/components/schemas/User' 62 | ``` 63 | -------------------------------------------------------------------------------- /spectral/functions/allOffTypesConsistency.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import { createRulesetFunction } from '@stoplight/spectral-core' 3 | 4 | export default createRulesetFunction( 5 | { 6 | input: null, 7 | options: null, 8 | }, 9 | function allOffTypesConsistency(targetVal, opts, context) { 10 | if (!targetVal || !Array.isArray(targetVal.allOf)) return 11 | 12 | const allOf = targetVal.allOf 13 | const resolvedDoc = context.documentInventory?.resolved || context.document.data 14 | 15 | // Вспомогательная функция для поиска значения по JSON Pointer 16 | const getByJsonPointer = (doc, pointer) => { 17 | if (!pointer.startsWith('#/')) return undefined 18 | return pointer 19 | .slice(2) 20 | .split('/') 21 | .reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), doc) 22 | } 23 | 24 | const types = [] 25 | 26 | for (const item of allOf) { 27 | if (item && item.$ref) { 28 | const resolved = getByJsonPointer(resolvedDoc, item.$ref) 29 | if (resolved && resolved.type) { 30 | types.push(resolved.type) 31 | } else { 32 | // если не нашёл тип по ссылке, просто пометим как "ref" 33 | types.push('ref') 34 | } 35 | } else if (item && item.type) { 36 | types.push(item.type) 37 | } 38 | } 39 | 40 | if (types.length === 0) return 41 | 42 | const firstType = types[0] 43 | const inconsistent = types.some((t) => t !== firstType) 44 | 45 | if (inconsistent) { 46 | return [ 47 | { 48 | message: `Элементы allOf должны иметь одинаковый тип. Найдены: ${types.join(', ')}`, 49 | path: [...context.path, 'allOf'], 50 | }, 51 | ] 52 | } 53 | }, 54 | ) 55 | -------------------------------------------------------------------------------- /spectral/tests/openapi/duplicated-entry-in-enum.test.ts: -------------------------------------------------------------------------------- 1 | import { retrieveDocument, setupSpectral } from '../utils/utils' 2 | import { Spectral } from '@stoplight/spectral-core' 3 | 4 | let linter: Spectral 5 | 6 | beforeAll(async () => { 7 | const rulesFile = './rules/openapi/duplicated-entry-in-enum.yaml' 8 | linter = await setupSpectral(rulesFile) 9 | }) 10 | 11 | test('should report an error when ENUM have duplicate entry', async () => { 12 | const specFile = './tests/openapi/testData/duplicated-entry-in-enum-spec-error.yaml' 13 | const spec = retrieveDocument(specFile) 14 | const results = await linter.run(spec) 15 | expect(results.length).toBe(1) 16 | expect(results[0].path.join('.')).toBe( 17 | 'components.schemas.TheGoodModel.properties.number_of_connectors.enum', 18 | ) 19 | expect(results[0].message).toBe("Duplicate entry '1,2,4,2' in enum.") 20 | }) 21 | 22 | test("should not report an error when ENUM don't have duplicate entry", async () => { 23 | const specFile = './tests/openapi/testData/duplicated-entry-in-enum-spec-valid.yaml' 24 | const spec = retrieveDocument(specFile) 25 | const results = await linter.run(spec) 26 | expect(results.length).toBe(0) 27 | }) 28 | 29 | test('should report an error when ENUM have duplicate entry in referenced file', async () => { 30 | const specFile = './tests/openapi/testData/ref-test-spec.yaml' 31 | const spec = retrieveDocument(specFile) 32 | const results = await linter.run(spec) 33 | // The ref.yaml contains duplicate entry '2' in enum, so we expect 1 error 34 | expect(results.length).toBe(1) 35 | expect(results[0].path.join('.')).toBe( 36 | 'paths./test.get.responses.200.content.application/json.schema', 37 | ) 38 | expect(results[0].message).toBe("Duplicate entry '[object Object]' in enum.") 39 | }) 40 | -------------------------------------------------------------------------------- /сontributing/VERSIONING.md: -------------------------------------------------------------------------------- 1 | # Процесс версионирования API Guide 2 | 3 | ## Общая информация 4 | 5 | API Guide использует семантическое версионирование ([SemVer](https://semver.org/)) для управления версиями. Версии устанавливаются в виде тегов в интерфейсе GitLab. 6 | 7 | Версия устанавливается на весь API Guide, а также на Spectral ruleset, которые используются для автоматических проверок. 8 | 9 | Каждый выпуск API Guide включает в себя: 10 | * Новую версию репозитория API Guide. Можно переключаться между версиями по тегам 11 | * Новую версию rulesets в директории `/spectral` 12 | * Новую версию npm пакета `@rapi/spectral-rulesets`, который содержит rulesets 13 | 14 | ## Выпуск новой версии API Guide 15 | 16 | При создании нового тега в репозитории запускается CI/CD пайплайн, который: 17 | 1. Собирает Spectral правила из директории `spectral/` 18 | 2. Формирует файлы `*-ruleset.yaml` из этих правил 19 | 3. Упаковывает файлы `*-ruleset.yaml` и директорию `functions` в npm пакет 20 | 4. Публикует npm пакет в Artifactory 21 | 5. Данный npm пакет можно подключать в проекты, использующие Spectral 22 | 23 | ## Стратегия выпуска версий 24 | 25 | Для минимизации частых изменений в API Guide: 26 | - Все изменения агрегируются в ветке `master` 27 | - Новые версии выпускаются не чаще одного раза в месяц 28 | - Выпуски производятся только при значительных изменениях или обновлениях 29 | 30 | ## Порядок действий для выпуска новой версии 31 | 32 | 1. Агрегируйте все необходимые изменения в ветку `master` 33 | 2. Убедитесь, что все тесты проходят успешно 34 | 3. Создайте новый тег в формате SemVer соблюдая порядок нумерации от предыдущего тега (например, `0.5.0`) в интерфейсе Gitlab 35 | 4. CI/CD пайплайн автоматически обработает тег и опубликует обновленные Spectral правила 36 | 5. Дальнейшая работа с API Guide может осуществляться в нужной версии, используя соответствующий тег -------------------------------------------------------------------------------- /spectral/functions/utils/getAllOperations.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // import { isPlainObject } from '@stoplight/json' 4 | import { isPlainObject } from './json.js' 5 | // Список допустимых HTTP‑методов, которые могут встречаться в OpenAPI. 6 | const validOperationKeys = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace'] 7 | 8 | /** 9 | * Генератор, который проходит по объекту "paths" в OpenAPI и 10 | * возвращает каждую найденную операцию. 11 | * 12 | * Пример структуры: 13 | * { 14 | * "/users": { get: {...}, post: {...} }, 15 | * "/pets": { get: {...} } 16 | * } 17 | * 18 | * На каждой итерации возвращается объект формата: 19 | * { path: "/users", operation: "get", value: {...} } 20 | * 21 | * @param {*} paths — объект OpenAPI.paths 22 | * @returns {IterableIterator<{ path: string, operation: string, value: object }>} 23 | */ 24 | function* getAllOperations(paths) { 25 | // Проверяем, что paths — это объект 26 | if (!isPlainObject(paths)) { 27 | return 28 | } 29 | 30 | // Перебираем все ключи верхнего уровня (пути, например "/users", "/pets") 31 | for (const path of Object.keys(paths)) { 32 | const operations = paths[path] 33 | 34 | if (!isPlainObject(operations)) { 35 | continue 36 | } 37 | 38 | // Для каждого пути перебираем методы (get, post, и т.д.) 39 | for (const operation of Object.keys(operations)) { 40 | // Проверяем, что значение — объект и что это допустимый HTTP‑метод 41 | if (!isPlainObject(operations[operation]) || !validOperationKeys.includes(operation)) { 42 | continue 43 | } 44 | 45 | // Возвращаем найденную операцию 46 | yield { 47 | path, // например: "/users" 48 | operation, // например: "get" 49 | value: operations[operation], // сам объект операции 50 | } 51 | } 52 | } 53 | } 54 | export { getAllOperations } 55 | -------------------------------------------------------------------------------- /spectral/functions/oasTagDefined.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import { createRulesetFunction } from '@stoplight/spectral-core' 3 | import { isObject } from './utils/isObject.js' 4 | import { getAllOperations } from './utils/getAllOperations.js' 5 | 6 | export default createRulesetFunction( 7 | { 8 | // На вход функции ожидается объект (весь документ OpenAPI) 9 | input: { 10 | type: 'object', 11 | }, 12 | options: null, // никаких дополнительных опций нет 13 | }, 14 | function oasTagDefined(targetVal) { 15 | // Список найденных несоответствий (ошибок) 16 | const results = [] 17 | 18 | // Собираем все глобальные теги в документе 19 | const globalTags = [] 20 | 21 | if (Array.isArray(targetVal.tags)) { 22 | for (const tag of targetVal.tags) { 23 | // Тег считается корректным, если это объект с полем name типа string 24 | if (isObject(tag) && typeof tag.name === 'string') { 25 | globalTags.push(tag.name) 26 | } 27 | } 28 | } 29 | 30 | // Достаём список всех операций (paths) 31 | const { paths } = targetVal 32 | 33 | // Перебираем операции 34 | for (const { path, operation, value } of getAllOperations(paths)) { 35 | if (!isObject(value)) continue 36 | 37 | const { tags } = value 38 | 39 | // Если у операции нет массива тегов — просто пропускаем 40 | if (!Array.isArray(tags)) { 41 | continue 42 | } 43 | 44 | // Проверяем каждый тег операции 45 | tags.forEach((tag, i) => { 46 | if (!globalTags.includes(tag)) { 47 | results.push({ 48 | message: 'Operation tags must be defined in global tags.', 49 | path: ['paths', path, operation, 'tags', i], 50 | }) 51 | } 52 | }) 53 | } 54 | 55 | // Возвращаем список ошибок (пустой — если всё корректно) 56 | return results 57 | }, 58 | ) 59 | -------------------------------------------------------------------------------- /rules/rule-format.md: -------------------------------------------------------------------------------- 1 | # Формат правил в API Best Practices 2 | 3 | - [Формат правил в API Best Practices](#формат-правил-в-api-best-practices) 4 | - [Обязательность](#обязательность) 5 | - [Содержимое правила](#содержимое-правила) 6 | - [Пример правила](#пример-правила) 7 | - [Использование kebab-case для пути](#использование-kebab-case-для-пути) 8 | - [Описание правила](#описание-правила) 9 | - [Обоснование](#обоснование) 10 | 11 | 12 | ### Обязательность 13 | Индикатор обязательности правил(Severity) имеет 2 значения 14 | - MUST - соблюдаем обязательно 15 | - RECOMMENDATION - рекомендуется для соблюдения 16 | 17 | 18 | ### Содержимое правила 19 | - Название, ID, Severity(MUST, RECOMMENDATION) 20 | - Описание с примерами(правильно, неправильно) 21 | - Обоснование(почему именно это решение принято, какие были альтернативы) 22 | 23 | ### Пример правила 24 | 25 | #### Использование kebab-case для пути 26 | 27 | | ID | Severity | Дата принятия | 28 | |-----------------|----------|---------------| 29 | | path-kebab-case | Must | 27.02.2025 | 30 | 31 | ##### Описание правила 32 | 33 | Пути API должны использовать kebab-case (строчные буквы с разделением дефисами) для наименования. 34 | 35 | Правильно: 36 | ``` 37 | /v1/statements 38 | /v1/payment-orders/ 39 | ``` 40 | Неправильно: 41 | ``` 42 | /v1/paymentOrders // camelCase 43 | /v1/PaymentOrders // PascalCase 44 | /v1/payment_orders // snake_case 45 | 46 | ``` 47 | ##### Обоснование 48 | 49 | Использование kebab-case обеспечивает единообразие API и соответствует лучшим практикам именования ресурсов в REST API. 50 | Чтобы ваши URI было легче сканировать и интерпретировать, используйте символ дефиса (-), чтобы улучшить читаемость имен в сегментах длинных путей. 51 | 52 | Были рассмотрены альтернативные стили именования: 53 | - camelCase - отклонён из-за проблем с регистро-зависимостью в некоторых системах 54 | - snake_case - отклонён для сохранения единообразия 55 | - PascalCase - отклонён из-за проблем с читаемостью URL 56 | 57 | --- --------------------------------------------------------------------------------