From 1b583f0716d6b1f8c88d69fac4db3edb917af734 Mon Sep 17 00:00:00 2001 From: DmitryAnansky Date: Wed, 13 Nov 2024 19:03:14 +0200 Subject: [PATCH] feat: add separate arazzo rule-set --- .changeset/purple-lobsters-stare.md | 6 + .changeset/strong-ties-argue.md | 7 + .gitignore | 2 +- .../snapshot.js | 1 + .../redocly.yaml | 2 +- .../snapshot.js | 2 +- .../snapshot.js | 2 +- .../config-with-warn.snapshot.js | 4 +- .../snapshot.js | 4 +- .../plugins/type-extention.js | 2 +- .../redocly.yaml | 4 +- .../snapshot.js | 2 +- __tests__/lint/async2/redocly.yaml | 2 +- __tests__/lint/async3/redocly.yaml | 2 +- .../deprecated-apiDefinitions/snapshot.js | 2 +- .../snapshot.js | 2 +- .../snapshot.js | 2 +- .../snapshot.js | 2 +- .../lint/null-schema-values/redocly.yaml | 2 +- __tests__/lint/null-schema-values/snapshot.js | 4 +- __tests__/lint/oas3.1-error/snapshot.js | 2 +- .../snapshot.js | 14 +- .../snapshot.js | 14 +- .../redocly.yaml | 2 +- .../snapshot.js | 14 +- __tests__/lint/spec-from/redocly.yaml | 2 +- __tests__/lint/spec-from/snapshot.js | 6 +- .../redocly.yaml | 2 +- .../lint/wrong-required-type/redocly.yaml | 2 +- .../lint/wrong-required-type/snapshot.js | 2 +- .../default-recommended-fallback/snapshot.js | 14 +- docs/changelog.md | 21 +- docs/configuration/reference/rules.md | 2 +- docs/configuration/rules.md | 2 +- docs/decorators/remove-unused-components.md | 2 +- docs/guides/response-contains-property.md | 2 +- docs/rules/async/channels-kebab-case.md | 78 +++++ docs/rules/async/no-channel-trailing-slash.md | 80 +++++ docs/rules/built-in-rules.md | 98 +++--- docs/rules/minimal.md | 50 +-- .../array-parameter-serialization.md | 4 +- .../{ => oas}/boolean-parameter-prefixes.md | 4 +- docs/rules/{ => oas}/component-name-unique.md | 2 +- docs/rules/{ => oas}/info-contact.md | 6 +- docs/rules/{ => oas}/info-license-url.md | 2 +- docs/rules/{ => oas}/info-license.md | 2 +- docs/rules/{ => oas}/no-ambiguous-paths.md | 2 +- docs/rules/{ => oas}/no-empty-servers.md | 2 +- docs/rules/{ => oas}/no-enum-type-mismatch.md | 4 +- .../no-example-value-and-externalValue.md | 6 +- .../rules/{ => oas}/no-http-verbs-in-paths.md | 4 +- docs/rules/{ => oas}/no-identical-paths.md | 4 +- .../no-invalid-media-type-examples.md | 2 +- .../no-invalid-parameter-examples.md | 2 +- .../{ => oas}/no-invalid-schema-examples.md | 2 +- .../rules/{ => oas}/no-path-trailing-slash.md | 2 +- ...no-required-schema-properties-undefined.md | 2 +- docs/rules/{ => oas}/no-server-example-com.md | 2 +- .../{ => oas}/no-server-trailing-slash.md | 2 +- .../no-server-variables-empty-enum.md | 2 +- .../{ => oas}/no-undefined-server-variable.md | 2 +- docs/rules/{ => oas}/no-unresolved-refs.md | 6 +- docs/rules/{ => oas}/no-unused-components.md | 2 +- .../rules/{ => oas}/operation-2xx-response.md | 2 +- .../operation-4xx-problem-details-rfc7807.md | 2 +- .../rules/{ => oas}/operation-4xx-response.md | 2 +- docs/rules/{ => oas}/operation-description.md | 6 +- .../{ => oas}/operation-operationId-unique.md | 6 +- .../operation-operationId-url-safe.md | 6 +- docs/rules/{ => oas}/operation-operationId.md | 4 +- .../{ => oas}/operation-parameters-unique.md | 2 +- .../rules/{ => oas}/operation-singular-tag.md | 2 +- docs/rules/{ => oas}/operation-summary.md | 4 +- docs/rules/{ => oas}/operation-tag-defined.md | 4 +- docs/rules/{ => oas}/parameter-description.md | 4 +- .../{ => oas}/path-declaration-must-exist.md | 4 +- .../rules/{ => oas}/path-excludes-patterns.md | 4 +- .../rules/{ => oas}/path-not-include-query.md | 4 +- .../{ => oas}/path-parameters-defined.md | 4 +- docs/rules/{ => oas}/path-segment-plural.md | 4 +- docs/rules/{ => oas}/paths-kebab-case.md | 4 +- docs/rules/{ => oas}/request-mime-type.md | 4 +- ...ired-string-property-missing-min-length.md | 6 +- .../{ => oas}/response-contains-header.md | 4 +- .../{ => oas}/response-contains-property.md | 4 +- docs/rules/{ => oas}/response-mime-type.md | 4 +- .../scalar-property-missing-example.md | 6 +- docs/rules/{ => oas}/security-defined.md | 4 +- .../spec-components-invalid-map-name.md | 6 +- docs/rules/{ => oas}/spec-strict-refs.md | 8 +- docs/rules/{ => oas}/tag-description.md | 6 +- docs/rules/{ => oas}/tags-alphabetical.md | 4 +- docs/rules/recommended.md | 56 ++-- docs/sidebars.yaml | 102 +++--- packages/cli/src/__tests__/utils.test.ts | 2 +- packages/cli/src/utils/miscellaneous.ts | 2 +- packages/core/__tests__/utils.ts | 3 - packages/core/src/__tests__/lint.test.ts | 6 +- packages/core/src/bundle.ts | 4 +- .../config-resolvers.test.ts.snap | 300 +++++++++++++----- .../__snapshots__/config.test.ts.snap | 19 +- .../config/__tests__/config-resolvers.test.ts | 16 +- .../core/src/config/__tests__/config.test.ts | 17 +- packages/core/src/config/all.ts | 178 ++++++++--- packages/core/src/config/builtIn.ts | 10 +- packages/core/src/config/config-resolvers.ts | 2 +- packages/core/src/config/config.ts | 52 ++- packages/core/src/config/minimal.ts | 174 +++++++--- .../core/src/config/recommended-strict.ts | 172 +++++++--- packages/core/src/config/recommended.ts | 170 +++++++--- packages/core/src/config/spec-arazzo.ts | 23 ++ packages/core/src/config/types.ts | 29 +- packages/core/src/config/utils.ts | 64 ++-- packages/core/src/index.ts | 2 +- packages/core/src/lint.ts | 4 +- packages/core/src/oas-types.ts | 34 +- .../arazzo/__tests__/criteria-unique.test.ts | 3 +- .../__tests__/no-actions-type-end.test.ts | 3 +- .../__tests__/no-criteria-xpath.test.ts | 3 +- .../__tests__/parameters-not-in-body.test.ts | 3 +- .../__tests__/parameters-unique.test.ts | 3 +- .../requestBody-replacements-unique.test.ts | 3 +- .../__tests__/source-description-type.test.ts | 6 +- .../sourceDescription-name-unique.test.ts | 3 +- .../sourceDescriptions-not-empty.test.ts | 104 ++++++ .../__tests__/step-onFailure-unique.test.ts | 3 +- .../__tests__/step-onSuccess-unique.test.ts | 3 +- .../arazzo/__tests__/stepId-unique.test.ts | 3 +- .../arazzo/__tests__/version-enum.test.ts | 3 +- .../__tests__/workflow-dependsOn.test.ts | 9 +- .../__tests__/workflowId-unique.test.ts | 6 +- .../core/src/rules/arazzo/criteria-unique.ts | 4 +- packages/core/src/rules/arazzo/index.ts | 40 +-- .../src/rules/arazzo/parameters-unique.ts | 4 +- .../arazzo/requestBody-replacements-unique.ts | 4 +- ...tion-type.ts => sourceDescription-type.ts} | 11 +- .../arazzo/sourceDescriptions-name-unique.ts | 4 +- .../arazzo/sourceDescriptions-not-empty.ts | 17 + .../src/rules/arazzo/step-onFailure-unique.ts | 4 +- .../src/rules/arazzo/step-onSuccess-unique.ts | 4 +- .../core/src/rules/arazzo/stepId-unique.ts | 4 +- .../src/rules/arazzo/workflow-dependsOn.ts | 4 +- .../src/rules/arazzo/workflowId-unique.ts | 4 +- packages/core/src/rules/async2/index.ts | 5 +- packages/core/src/rules/async3/index.ts | 6 +- .../__tests__/no-enum-type-mismatch.test.ts | 2 +- .../{spec.test.ts => struct.test.ts} | 70 ++-- .../src/rules/common/{spec.ts => struct.ts} | 4 +- packages/core/src/rules/oas2/index.ts | 5 +- .../rules/oas3/__tests__/spec/spec.test.ts | 20 +- packages/core/src/rules/oas3/index.ts | 5 +- .../src/rules/spot/no-actions-type-end.ts | 4 +- .../core/src/rules/spot/no-criteria-xpath.ts | 4 +- .../src/rules/spot/parameters-not-in-body.ts | 4 +- packages/core/src/rules/spot/version-enum.ts | 4 +- packages/core/src/types/arazzo.ts | 16 +- packages/core/src/types/redocly-yaml.ts | 111 ++++++- packages/core/src/typings/arazzo.ts | 11 +- packages/core/src/utils.ts | 6 +- packages/core/src/visitors.ts | 8 +- 160 files changed, 1779 insertions(+), 866 deletions(-) create mode 100644 .changeset/purple-lobsters-stare.md create mode 100644 .changeset/strong-ties-argue.md create mode 100644 docs/rules/async/channels-kebab-case.md create mode 100644 docs/rules/async/no-channel-trailing-slash.md rename docs/rules/{ => oas}/array-parameter-serialization.md (96%) rename docs/rules/{ => oas}/boolean-parameter-prefixes.md (96%) rename docs/rules/{ => oas}/component-name-unique.md (98%) rename docs/rules/{ => oas}/info-contact.md (93%) rename docs/rules/{ => oas}/info-license-url.md (97%) rename docs/rules/{ => oas}/info-license.md (97%) rename docs/rules/{ => oas}/no-ambiguous-paths.md (98%) rename docs/rules/{ => oas}/no-empty-servers.md (97%) rename docs/rules/{ => oas}/no-enum-type-mismatch.md (96%) rename docs/rules/{ => oas}/no-example-value-and-externalValue.md (95%) rename docs/rules/{ => oas}/no-http-verbs-in-paths.md (96%) rename docs/rules/{ => oas}/no-identical-paths.md (96%) rename docs/rules/{ => oas}/no-invalid-media-type-examples.md (98%) rename docs/rules/{ => oas}/no-invalid-parameter-examples.md (97%) rename docs/rules/{ => oas}/no-invalid-schema-examples.md (97%) rename docs/rules/{ => oas}/no-path-trailing-slash.md (97%) rename docs/rules/{ => oas}/no-required-schema-properties-undefined.md (97%) rename docs/rules/{ => oas}/no-server-example-com.md (97%) rename docs/rules/{ => oas}/no-server-trailing-slash.md (97%) rename docs/rules/{ => oas}/no-server-variables-empty-enum.md (97%) rename docs/rules/{ => oas}/no-undefined-server-variable.md (97%) rename docs/rules/{ => oas}/no-unresolved-refs.md (94%) rename docs/rules/{ => oas}/no-unused-components.md (97%) rename docs/rules/{ => oas}/operation-2xx-response.md (97%) rename docs/rules/{ => oas}/operation-4xx-problem-details-rfc7807.md (97%) rename docs/rules/{ => oas}/operation-4xx-response.md (97%) rename docs/rules/{ => oas}/operation-description.md (88%) rename docs/rules/{ => oas}/operation-operationId-unique.md (87%) rename docs/rules/{ => oas}/operation-operationId-url-safe.md (86%) rename docs/rules/{ => oas}/operation-operationId.md (89%) rename docs/rules/{ => oas}/operation-parameters-unique.md (97%) rename docs/rules/{ => oas}/operation-singular-tag.md (97%) rename docs/rules/{ => oas}/operation-summary.md (94%) rename docs/rules/{ => oas}/operation-tag-defined.md (95%) rename docs/rules/{ => oas}/parameter-description.md (94%) rename docs/rules/{ => oas}/path-declaration-must-exist.md (94%) rename docs/rules/{ => oas}/path-excludes-patterns.md (95%) rename docs/rules/{ => oas}/path-not-include-query.md (94%) rename docs/rules/{ => oas}/path-parameters-defined.md (94%) rename docs/rules/{ => oas}/path-segment-plural.md (96%) rename docs/rules/{ => oas}/paths-kebab-case.md (95%) rename docs/rules/{ => oas}/request-mime-type.md (95%) rename docs/rules/{ => oas}/required-string-property-missing-min-length.md (91%) rename docs/rules/{ => oas}/response-contains-header.md (96%) rename docs/rules/{ => oas}/response-contains-property.md (96%) rename docs/rules/{ => oas}/response-mime-type.md (95%) rename docs/rules/{ => oas}/scalar-property-missing-example.md (93%) rename docs/rules/{ => oas}/security-defined.md (96%) rename docs/rules/{ => oas}/spec-components-invalid-map-name.md (94%) rename docs/rules/{ => oas}/spec-strict-refs.md (92%) rename docs/rules/{ => oas}/tag-description.md (93%) rename docs/rules/{ => oas}/tags-alphabetical.md (96%) create mode 100644 packages/core/src/config/spec-arazzo.ts create mode 100644 packages/core/src/rules/arazzo/__tests__/sourceDescriptions-not-empty.test.ts rename packages/core/src/rules/arazzo/{source-description-type.ts => sourceDescription-type.ts} (53%) create mode 100644 packages/core/src/rules/arazzo/sourceDescriptions-not-empty.ts rename packages/core/src/rules/common/__tests__/{spec.test.ts => struct.test.ts} (92%) rename packages/core/src/rules/common/{spec.ts => struct.ts} (98%) diff --git a/.changeset/purple-lobsters-stare.md b/.changeset/purple-lobsters-stare.md new file mode 100644 index 0000000000..b2246a232b --- /dev/null +++ b/.changeset/purple-lobsters-stare.md @@ -0,0 +1,6 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Updated `sourceDescriptions` to enforce a valid type field, ensuring compliance with the Arazzo specification. diff --git a/.changeset/strong-ties-argue.md b/.changeset/strong-ties-argue.md new file mode 100644 index 0000000000..78d80d21ef --- /dev/null +++ b/.changeset/strong-ties-argue.md @@ -0,0 +1,7 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Introduced `struct` rule. +Added Arazzo version 1 ruleset. diff --git a/.gitignore b/.gitignore index bdee3c94d4..dbf7187888 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ output/ *.tsbuildinfo *.tgz redoc-static.html -packages/cli/README.md +packages/cli/README.md \ No newline at end of file diff --git a/__tests__/check-config/config-type-extensions-in-assertions/snapshot.js b/__tests__/check-config/config-type-extensions-in-assertions/snapshot.js index 77d1c145a0..d1e66c488e 100644 --- a/__tests__/check-config/config-type-extensions-in-assertions/snapshot.js +++ b/__tests__/check-config/config-type-extensions-in-assertions/snapshot.js @@ -2,6 +2,7 @@ exports[`E2E check-config config type extension in assertions 1`] = ` +The 'spec' field is deprecated. Use struct instead. ✅ Your config is valid. `; diff --git a/__tests__/check-config/wrong-config-type-extensions-in-assertions/redocly.yaml b/__tests__/check-config/wrong-config-type-extensions-in-assertions/redocly.yaml index f12a33c1b7..47128825f7 100644 --- a/__tests__/check-config/wrong-config-type-extensions-in-assertions/redocly.yaml +++ b/__tests__/check-config/wrong-config-type-extensions-in-assertions/redocly.yaml @@ -4,7 +4,7 @@ plugins: - plugins/type-extention.js rules: - spec: warn + struct: warn rule/metadata-lifecycle: subject: type: WrongXMetaData diff --git a/__tests__/check-config/wrong-config-type-extensions-in-assertions/snapshot.js b/__tests__/check-config/wrong-config-type-extensions-in-assertions/snapshot.js index fe75e0df16..eb312666fa 100644 --- a/__tests__/check-config/wrong-config-type-extensions-in-assertions/snapshot.js +++ b/__tests__/check-config/wrong-config-type-extensions-in-assertions/snapshot.js @@ -5,7 +5,7 @@ exports[`E2E check-config wrong config type extension in assertions 1`] = ` Deprecated plugin format detected: type-extension [1] redocly.yaml:10:13 at #/rules/rule~1metadata-lifecycle/subject/type -\`type\` can be one of the following only: "any", "Root", "Tag", "TagList", "TagGroups", "TagGroup", "ExternalDocs", "Example", "ExamplesMap", "EnumDescriptions", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Logo", "Paths", "PathItem", "Parameter", "ParameterItems", "ParameterList", "Operation", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "XCodeSample", "XCodeSampleList", "XServerList", "XServer", "Server", "ServerList", "ServerVariable", "ServerVariablesMap", "Callback", "CallbacksMap", "RequestBody", "MediaTypesMap", "MediaType", "Encoding", "EncodingMap", "HeadersMap", "Link", "DiscriminatorMapping", "Discriminator", "Components", "LinksMap", "NamedExamples", "NamedRequestBodies", "NamedHeaders", "NamedLinks", "NamedCallbacks", "ImplicitFlow", "PasswordFlow", "ClientCredentials", "AuthorizationCode", "OAuth2Flows", "XUsePkce", "WebhooksMap", "XMetaData", "PatternProperties", "NamedPathItems", "DependentRequired", "HttpServerBinding", "HttpChannelBinding", "HttpMessageBinding", "HttpOperationBinding", "WsServerBinding", "WsChannelBinding", "WsMessageBinding", "WsOperationBinding", "KafkaServerBinding", "KafkaTopicConfiguration", "KafkaChannelBinding", "KafkaMessageBinding", "KafkaOperationBinding", "AnypointmqServerBinding", "AnypointmqChannelBinding", "AnypointmqMessageBinding", "AnypointmqOperationBinding", "AmqpServerBinding", "AmqpChannelBinding", "AmqpMessageBinding", "AmqpOperationBinding", "Amqp1ServerBinding", "Amqp1ChannelBinding", "Amqp1MessageBinding", "Amqp1OperationBinding", "MqttServerBindingLastWill", "MqttServerBinding", "MqttChannelBinding", "MqttMessageBinding", "MqttOperationBinding", "Mqtt5ServerBinding", "Mqtt5ChannelBinding", "Mqtt5MessageBinding", "Mqtt5OperationBinding", "NatsServerBinding", "NatsChannelBinding", "NatsMessageBinding", "NatsOperationBinding", "JmsServerBinding", "JmsChannelBinding", "JmsMessageBinding", "JmsOperationBinding", "SolaceServerBinding", "SolaceChannelBinding", "SolaceMessageBinding", "SolaceDestination", "SolaceOperationBinding", "StompServerBinding", "StompChannelBinding", "StompMessageBinding", "StompOperationBinding", "RedisServerBinding", "RedisChannelBinding", "RedisMessageBinding", "RedisOperationBinding", "MercureServerBinding", "MercureChannelBinding", "MercureMessageBinding", "MercureOperationBinding", "ServerBindings", "ChannelBindings", "MessageBindings", "OperationBindings", "ServerMap", "ChannelMap", "Channel", "ParametersMap", "MessageExample", "NamedMessages", "NamedMessageTraits", "NamedOperationTraits", "NamedCorrelationIds", "SecuritySchemeFlows", "Message", "OperationTrait", "OperationTraitList", "MessageTrait", "MessageTraitList", "MessageExampleList", "CorrelationId", "Dependencies", "OperationReply", "OperationReplyAddress", "NamedTags", "NamedExternalDocs", "NamedChannels", "NamedOperations", "NamedOperationReplies", "NamedOperationRelyAddresses", "SecuritySchemeList", "MessageList", "SourceDescriptions", "OpenAPISourceDescription", "NoneSourceDescription", "ArazzoSourceDescription", "Parameters", "ReusableObject", "Workflows", "Workflow", "Steps", "Step", "Replacement", "ExtendedOperation", "ExpectSchema", "Outputs", "CriterionObject", "XPathCriterion", "JSONPathCriterion", "SuccessActionObject", "OnSuccessActionList", "FailureActionObject", "OnFailureActionList", "NamedInputs", "NamedSuccessActions", "NamedFailureActions", "SpecExtension". +\`type\` can be one of the following only: "any", "Root", "Tag", "TagList", "TagGroups", "TagGroup", "ExternalDocs", "Example", "ExamplesMap", "EnumDescriptions", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Logo", "Paths", "PathItem", "Parameter", "ParameterItems", "ParameterList", "Operation", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "XCodeSample", "XCodeSampleList", "XServerList", "XServer", "Server", "ServerList", "ServerVariable", "ServerVariablesMap", "Callback", "CallbacksMap", "RequestBody", "MediaTypesMap", "MediaType", "Encoding", "EncodingMap", "HeadersMap", "Link", "DiscriminatorMapping", "Discriminator", "Components", "LinksMap", "NamedExamples", "NamedRequestBodies", "NamedHeaders", "NamedLinks", "NamedCallbacks", "ImplicitFlow", "PasswordFlow", "ClientCredentials", "AuthorizationCode", "OAuth2Flows", "XUsePkce", "WebhooksMap", "XMetaData", "PatternProperties", "NamedPathItems", "DependentRequired", "HttpServerBinding", "HttpChannelBinding", "HttpMessageBinding", "HttpOperationBinding", "WsServerBinding", "WsChannelBinding", "WsMessageBinding", "WsOperationBinding", "KafkaServerBinding", "KafkaTopicConfiguration", "KafkaChannelBinding", "KafkaMessageBinding", "KafkaOperationBinding", "AnypointmqServerBinding", "AnypointmqChannelBinding", "AnypointmqMessageBinding", "AnypointmqOperationBinding", "AmqpServerBinding", "AmqpChannelBinding", "AmqpMessageBinding", "AmqpOperationBinding", "Amqp1ServerBinding", "Amqp1ChannelBinding", "Amqp1MessageBinding", "Amqp1OperationBinding", "MqttServerBindingLastWill", "MqttServerBinding", "MqttChannelBinding", "MqttMessageBinding", "MqttOperationBinding", "Mqtt5ServerBinding", "Mqtt5ChannelBinding", "Mqtt5MessageBinding", "Mqtt5OperationBinding", "NatsServerBinding", "NatsChannelBinding", "NatsMessageBinding", "NatsOperationBinding", "JmsServerBinding", "JmsChannelBinding", "JmsMessageBinding", "JmsOperationBinding", "SolaceServerBinding", "SolaceChannelBinding", "SolaceMessageBinding", "SolaceDestination", "SolaceOperationBinding", "StompServerBinding", "StompChannelBinding", "StompMessageBinding", "StompOperationBinding", "RedisServerBinding", "RedisChannelBinding", "RedisMessageBinding", "RedisOperationBinding", "MercureServerBinding", "MercureChannelBinding", "MercureMessageBinding", "MercureOperationBinding", "ServerBindings", "ChannelBindings", "MessageBindings", "OperationBindings", "ServerMap", "ChannelMap", "Channel", "ParametersMap", "MessageExample", "NamedMessages", "NamedMessageTraits", "NamedOperationTraits", "NamedCorrelationIds", "SecuritySchemeFlows", "Message", "OperationTrait", "OperationTraitList", "MessageTrait", "MessageTraitList", "MessageExampleList", "CorrelationId", "Dependencies", "OperationReply", "OperationReplyAddress", "NamedTags", "NamedExternalDocs", "NamedChannels", "NamedOperations", "NamedOperationReplies", "NamedOperationRelyAddresses", "SecuritySchemeList", "MessageList", "SourceDescriptions", "OpenAPISourceDescription", "ArazzoSourceDescription", "Parameters", "ReusableObject", "Workflows", "Workflow", "Steps", "Step", "Replacement", "ExtendedOperation", "ExpectSchema", "Outputs", "CriterionObject", "XPathCriterion", "JSONPathCriterion", "SuccessActionObject", "OnSuccessActionList", "FailureActionObject", "OnFailureActionList", "NamedInputs", "NamedSuccessActions", "NamedFailureActions", "SpecExtension". 8 | rule/metadata-lifecycle: 9 | subject: diff --git a/__tests__/lint-config/invalid-config-assertation-config-type/snapshot.js b/__tests__/lint-config/invalid-config-assertation-config-type/snapshot.js index d07c1737f5..b45b5c0013 100644 --- a/__tests__/lint-config/invalid-config-assertation-config-type/snapshot.js +++ b/__tests__/lint-config/invalid-config-assertation-config-type/snapshot.js @@ -6,7 +6,7 @@ exports[`E2E lint-config test with option: { dirName: 'invalid-config-assertatio The 'assert/' syntax in assert/path-item-mutually-required is deprecated. Update your configuration to use 'rule/' instead. Examples and more information: https://redocly.com/docs/cli/rules/configurable-rules/ [1] .redocly.yaml:9:17 at #/rules/assert~1path-item-mutually-required/where/0/subject/type -\`type\` can be one of the following only: "any", "Root", "Tag", "TagList", "TagGroups", "TagGroup", "ExternalDocs", "Example", "ExamplesMap", "EnumDescriptions", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Logo", "Paths", "PathItem", "Parameter", "ParameterItems", "ParameterList", "Operation", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "XCodeSample", "XCodeSampleList", "XServerList", "XServer", "Server", "ServerList", "ServerVariable", "ServerVariablesMap", "Callback", "CallbacksMap", "RequestBody", "MediaTypesMap", "MediaType", "Encoding", "EncodingMap", "HeadersMap", "Link", "DiscriminatorMapping", "Discriminator", "Components", "LinksMap", "NamedExamples", "NamedRequestBodies", "NamedHeaders", "NamedLinks", "NamedCallbacks", "ImplicitFlow", "PasswordFlow", "ClientCredentials", "AuthorizationCode", "OAuth2Flows", "XUsePkce", "WebhooksMap", "PatternProperties", "NamedPathItems", "DependentRequired", "HttpServerBinding", "HttpChannelBinding", "HttpMessageBinding", "HttpOperationBinding", "WsServerBinding", "WsChannelBinding", "WsMessageBinding", "WsOperationBinding", "KafkaServerBinding", "KafkaTopicConfiguration", "KafkaChannelBinding", "KafkaMessageBinding", "KafkaOperationBinding", "AnypointmqServerBinding", "AnypointmqChannelBinding", "AnypointmqMessageBinding", "AnypointmqOperationBinding", "AmqpServerBinding", "AmqpChannelBinding", "AmqpMessageBinding", "AmqpOperationBinding", "Amqp1ServerBinding", "Amqp1ChannelBinding", "Amqp1MessageBinding", "Amqp1OperationBinding", "MqttServerBindingLastWill", "MqttServerBinding", "MqttChannelBinding", "MqttMessageBinding", "MqttOperationBinding", "Mqtt5ServerBinding", "Mqtt5ChannelBinding", "Mqtt5MessageBinding", "Mqtt5OperationBinding", "NatsServerBinding", "NatsChannelBinding", "NatsMessageBinding", "NatsOperationBinding", "JmsServerBinding", "JmsChannelBinding", "JmsMessageBinding", "JmsOperationBinding", "SolaceServerBinding", "SolaceChannelBinding", "SolaceMessageBinding", "SolaceDestination", "SolaceOperationBinding", "StompServerBinding", "StompChannelBinding", "StompMessageBinding", "StompOperationBinding", "RedisServerBinding", "RedisChannelBinding", "RedisMessageBinding", "RedisOperationBinding", "MercureServerBinding", "MercureChannelBinding", "MercureMessageBinding", "MercureOperationBinding", "ServerBindings", "ChannelBindings", "MessageBindings", "OperationBindings", "ServerMap", "ChannelMap", "Channel", "ParametersMap", "MessageExample", "NamedMessages", "NamedMessageTraits", "NamedOperationTraits", "NamedCorrelationIds", "SecuritySchemeFlows", "Message", "OperationTrait", "OperationTraitList", "MessageTrait", "MessageTraitList", "MessageExampleList", "CorrelationId", "Dependencies", "OperationReply", "OperationReplyAddress", "NamedTags", "NamedExternalDocs", "NamedChannels", "NamedOperations", "NamedOperationReplies", "NamedOperationRelyAddresses", "SecuritySchemeList", "MessageList", "SourceDescriptions", "OpenAPISourceDescription", "NoneSourceDescription", "ArazzoSourceDescription", "Parameters", "ReusableObject", "Workflows", "Workflow", "Steps", "Step", "Replacement", "ExtendedOperation", "ExpectSchema", "Outputs", "CriterionObject", "XPathCriterion", "JSONPathCriterion", "SuccessActionObject", "OnSuccessActionList", "FailureActionObject", "OnFailureActionList", "NamedInputs", "NamedSuccessActions", "NamedFailureActions", "SpecExtension". +\`type\` can be one of the following only: "any", "Root", "Tag", "TagList", "TagGroups", "TagGroup", "ExternalDocs", "Example", "ExamplesMap", "EnumDescriptions", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Logo", "Paths", "PathItem", "Parameter", "ParameterItems", "ParameterList", "Operation", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "XCodeSample", "XCodeSampleList", "XServerList", "XServer", "Server", "ServerList", "ServerVariable", "ServerVariablesMap", "Callback", "CallbacksMap", "RequestBody", "MediaTypesMap", "MediaType", "Encoding", "EncodingMap", "HeadersMap", "Link", "DiscriminatorMapping", "Discriminator", "Components", "LinksMap", "NamedExamples", "NamedRequestBodies", "NamedHeaders", "NamedLinks", "NamedCallbacks", "ImplicitFlow", "PasswordFlow", "ClientCredentials", "AuthorizationCode", "OAuth2Flows", "XUsePkce", "WebhooksMap", "PatternProperties", "NamedPathItems", "DependentRequired", "HttpServerBinding", "HttpChannelBinding", "HttpMessageBinding", "HttpOperationBinding", "WsServerBinding", "WsChannelBinding", "WsMessageBinding", "WsOperationBinding", "KafkaServerBinding", "KafkaTopicConfiguration", "KafkaChannelBinding", "KafkaMessageBinding", "KafkaOperationBinding", "AnypointmqServerBinding", "AnypointmqChannelBinding", "AnypointmqMessageBinding", "AnypointmqOperationBinding", "AmqpServerBinding", "AmqpChannelBinding", "AmqpMessageBinding", "AmqpOperationBinding", "Amqp1ServerBinding", "Amqp1ChannelBinding", "Amqp1MessageBinding", "Amqp1OperationBinding", "MqttServerBindingLastWill", "MqttServerBinding", "MqttChannelBinding", "MqttMessageBinding", "MqttOperationBinding", "Mqtt5ServerBinding", "Mqtt5ChannelBinding", "Mqtt5MessageBinding", "Mqtt5OperationBinding", "NatsServerBinding", "NatsChannelBinding", "NatsMessageBinding", "NatsOperationBinding", "JmsServerBinding", "JmsChannelBinding", "JmsMessageBinding", "JmsOperationBinding", "SolaceServerBinding", "SolaceChannelBinding", "SolaceMessageBinding", "SolaceDestination", "SolaceOperationBinding", "StompServerBinding", "StompChannelBinding", "StompMessageBinding", "StompOperationBinding", "RedisServerBinding", "RedisChannelBinding", "RedisMessageBinding", "RedisOperationBinding", "MercureServerBinding", "MercureChannelBinding", "MercureMessageBinding", "MercureOperationBinding", "ServerBindings", "ChannelBindings", "MessageBindings", "OperationBindings", "ServerMap", "ChannelMap", "Channel", "ParametersMap", "MessageExample", "NamedMessages", "NamedMessageTraits", "NamedOperationTraits", "NamedCorrelationIds", "SecuritySchemeFlows", "Message", "OperationTrait", "OperationTraitList", "MessageTrait", "MessageTraitList", "MessageExampleList", "CorrelationId", "Dependencies", "OperationReply", "OperationReplyAddress", "NamedTags", "NamedExternalDocs", "NamedChannels", "NamedOperations", "NamedOperationReplies", "NamedOperationRelyAddresses", "SecuritySchemeList", "MessageList", "SourceDescriptions", "OpenAPISourceDescription", "ArazzoSourceDescription", "Parameters", "ReusableObject", "Workflows", "Workflow", "Steps", "Step", "Replacement", "ExtendedOperation", "ExpectSchema", "Outputs", "CriterionObject", "XPathCriterion", "JSONPathCriterion", "SuccessActionObject", "OnSuccessActionList", "FailureActionObject", "OnFailureActionList", "NamedInputs", "NamedSuccessActions", "NamedFailureActions", "SpecExtension". 7 | where: 8 | - subject: diff --git a/__tests__/lint-config/invalid-definition-and-config/config-with-warn.snapshot.js b/__tests__/lint-config/invalid-definition-and-config/config-with-warn.snapshot.js index f954d0998a..9777891125 100644 --- a/__tests__/lint-config/invalid-definition-and-config/config-with-warn.snapshot.js +++ b/__tests__/lint-config/invalid-definition-and-config/config-with-warn.snapshot.js @@ -33,7 +33,7 @@ The field \`title\` must be present on this level. 5 | description: Example description 6 | version: '1.0' -Error was generated by the spec rule. +Error was generated by the struct rule. [2] ../__fixtures__/invalid-openapi.yaml:10:5 at #/paths/~1pet~1findByStatus/get/summary @@ -60,7 +60,7 @@ Expected type \`Responses\` (object) but got \`null\` | ^^^^^^^^^^ 12 | -Error was generated by the spec rule. +Error was generated by the struct rule. [4] ../__fixtures__/invalid-openapi.yaml:4:1 at #/info diff --git a/__tests__/lint/arazzo-not-valid-test-description/snapshot.js b/__tests__/lint/arazzo-not-valid-test-description/snapshot.js index acf0992022..f3a4a359de 100644 --- a/__tests__/lint/arazzo-not-valid-test-description/snapshot.js +++ b/__tests__/lint/arazzo-not-valid-test-description/snapshot.js @@ -18,7 +18,7 @@ The field \`info\` must be present on this level. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | -Error was generated by the spec rule. +Error was generated by the struct rule. [2] museum.yaml:9:5 at #/workflows/0 @@ -36,7 +36,7 @@ The field \`steps\` must be present on this level. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | -Error was generated by the spec rule. +Error was generated by the struct rule. museum.yaml: validated in ms diff --git a/__tests__/lint/arazzo-type-extensions-with-plugin/plugins/type-extention.js b/__tests__/lint/arazzo-type-extensions-with-plugin/plugins/type-extention.js index 1d5049c181..d3d2e80912 100644 --- a/__tests__/lint/arazzo-type-extensions-with-plugin/plugins/type-extention.js +++ b/__tests__/lint/arazzo-type-extensions-with-plugin/plugins/type-extention.js @@ -9,7 +9,7 @@ const XMetaData = { module.exports = { id: 'type-extension', typeExtension: { - arazzo(types) { + arazzo1(types) { newTypes = { ...types, XMetaData: XMetaData, diff --git a/__tests__/lint/arazzo-type-extensions-with-plugin/redocly.yaml b/__tests__/lint/arazzo-type-extensions-with-plugin/redocly.yaml index ae54d08d69..91db16b46e 100644 --- a/__tests__/lint/arazzo-type-extensions-with-plugin/redocly.yaml +++ b/__tests__/lint/arazzo-type-extensions-with-plugin/redocly.yaml @@ -1,5 +1,5 @@ plugins: - plugins/type-extention.js -arazzoRules: - spec: error +arazzo1Rules: + struct: error diff --git a/__tests__/lint/arazzo-type-extensions-with-plugin/snapshot.js b/__tests__/lint/arazzo-type-extensions-with-plugin/snapshot.js index 8c43799e25..dfdc90ab42 100644 --- a/__tests__/lint/arazzo-type-extensions-with-plugin/snapshot.js +++ b/__tests__/lint/arazzo-type-extensions-with-plugin/snapshot.js @@ -15,7 +15,7 @@ Property \`wrong-key\` is not expected here. 9 | metadata: 10 | lifecycle: production -Error was generated by the spec rule. +Error was generated by the struct rule. museum.yaml: validated in ms diff --git a/__tests__/lint/async2/redocly.yaml b/__tests__/lint/async2/redocly.yaml index d344cf2a83..44d8389fbb 100644 --- a/__tests__/lint/async2/redocly.yaml +++ b/__tests__/lint/async2/redocly.yaml @@ -35,4 +35,4 @@ apis: root: ./websocket-gemini.yml rules: - spec: error + struct: error diff --git a/__tests__/lint/async3/redocly.yaml b/__tests__/lint/async3/redocly.yaml index f84e144191..c04299899c 100644 --- a/__tests__/lint/async3/redocly.yaml +++ b/__tests__/lint/async3/redocly.yaml @@ -33,4 +33,4 @@ apis: root: ./websocket-gemini.yml rules: - spec: error + struct: error diff --git a/__tests__/lint/deprecated-apiDefinitions/snapshot.js b/__tests__/lint/deprecated-apiDefinitions/snapshot.js index e5c05e3e47..29f48eecc2 100644 --- a/__tests__/lint/deprecated-apiDefinitions/snapshot.js +++ b/__tests__/lint/deprecated-apiDefinitions/snapshot.js @@ -2,7 +2,7 @@ exports[`E2E lint deprecated-apiDefinitions 1`] = ` -The 'apiDefinitions' field is deprecated. Use apis instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties +The 'apiDefinitions' field is deprecated. Use apis instead. The 'lint' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties [1] redocly.yaml:1:1 at #/apiDefinitions diff --git a/__tests__/lint/no-enum-type-mismatch-error-recommended-config/snapshot.js b/__tests__/lint/no-enum-type-mismatch-error-recommended-config/snapshot.js index 47dc235cc6..5c71cd405f 100644 --- a/__tests__/lint/no-enum-type-mismatch-error-recommended-config/snapshot.js +++ b/__tests__/lint/no-enum-type-mismatch-error-recommended-config/snapshot.js @@ -39,7 +39,7 @@ Expected type \`array\` but got \`string\`. | ^^^^^^ 46 | -Error was generated by the spec rule. +Error was generated by the struct rule. [4] openapi.yaml:2:1 at #/info diff --git a/__tests__/lint/no-invalid-media-type-examples-invalid-schema/snapshot.js b/__tests__/lint/no-invalid-media-type-examples-invalid-schema/snapshot.js index 9d84b1e8e4..1569745716 100644 --- a/__tests__/lint/no-invalid-media-type-examples-invalid-schema/snapshot.js +++ b/__tests__/lint/no-invalid-media-type-examples-invalid-schema/snapshot.js @@ -14,7 +14,7 @@ The \`type\` field must be defined when the \`nullable\` field is used. 17 | paths: 18 | /test: -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:28:17 at #/paths/~1test/get/responses/202/content/application~1json/schema diff --git a/__tests__/lint/no-undefined-server-variable-error-recommended-config/snapshot.js b/__tests__/lint/no-undefined-server-variable-error-recommended-config/snapshot.js index 407e57fe08..70caf2fbcc 100644 --- a/__tests__/lint/no-undefined-server-variable-error-recommended-config/snapshot.js +++ b/__tests__/lint/no-undefined-server-variable-error-recommended-config/snapshot.js @@ -14,7 +14,7 @@ Expected type \`string\` but got \`null\`. 8 | description: Dev Environment. 9 | security: [] -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:2:1 at #/info diff --git a/__tests__/lint/null-schema-values/redocly.yaml b/__tests__/lint/null-schema-values/redocly.yaml index 313f35207c..8d04f19db3 100644 --- a/__tests__/lint/null-schema-values/redocly.yaml +++ b/__tests__/lint/null-schema-values/redocly.yaml @@ -3,5 +3,5 @@ apis: root: ./openapi.yaml rules: - spec: error + struct: error no-unused-components: error diff --git a/__tests__/lint/null-schema-values/snapshot.js b/__tests__/lint/null-schema-values/snapshot.js index df0c31baf4..a88dcbfac4 100644 --- a/__tests__/lint/null-schema-values/snapshot.js +++ b/__tests__/lint/null-schema-values/snapshot.js @@ -13,7 +13,7 @@ Expected type \`Info\` (object) but got \`null\` 3 | paths: 4 | /test: -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:15:5 at #/components/schemas/EmptySchema @@ -28,7 +28,7 @@ Expected type \`Schema\` (object) but got \`null\` referenced from openapi.yaml:12:17 at #/paths/~1test/get/responses/200/content/application~1json/schema -Error was generated by the spec rule. +Error was generated by the struct rule. /openapi.yaml: validated in ms diff --git a/__tests__/lint/oas3.1-error/snapshot.js b/__tests__/lint/oas3.1-error/snapshot.js index c478166fe8..5c9a575307 100644 --- a/__tests__/lint/oas3.1-error/snapshot.js +++ b/__tests__/lint/oas3.1-error/snapshot.js @@ -16,7 +16,7 @@ Must contain at least one of the following fields: paths, components, webhooks. | ^^^^^^^^^^^^ 24 | -Error was generated by the spec rule. +Error was generated by the struct rule. /openapi.yaml: validated in ms diff --git a/__tests__/lint/operation-security-scheme-oas2-error/snapshot.js b/__tests__/lint/operation-security-scheme-oas2-error/snapshot.js index d6b32a167a..c12c6a5814 100644 --- a/__tests__/lint/operation-security-scheme-oas2-error/snapshot.js +++ b/__tests__/lint/operation-security-scheme-oas2-error/snapshot.js @@ -14,7 +14,7 @@ The field \`name\` is not allowed here. 15 | description: basic auth 16 | x-internal: true -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:22:5 at #/securityDefinitions/bearerAuth/flows @@ -30,7 +30,7 @@ Did you mean: flow ? 23 | x-internal: true 24 | testProp: test -Error was generated by the spec rule. +Error was generated by the struct rule. [3] openapi.yaml:24:5 at #/securityDefinitions/bearerAuth/testProp @@ -44,7 +44,7 @@ Property \`testProp\` is not expected here. 25 | oauthImplicit: 26 | type: oauth2 -Error was generated by the spec rule. +Error was generated by the struct rule. [4] openapi.yaml:30:5 at #/securityDefinitions/oauthImplicit/tokenUrl @@ -58,7 +58,7 @@ The field \`tokenUrl\` is not allowed here. 31 | scopes: 32 | 'write:pets': 'modify pets in your account' -Error was generated by the spec rule. +Error was generated by the struct rule. [5] openapi.yaml:40:5 at #/securityDefinitions/oauthAccessCode/name @@ -72,7 +72,7 @@ The field \`name\` is not allowed here. 41 | scopes: 42 | 'write:pets': 'modify pets in your account' -Error was generated by the spec rule. +Error was generated by the struct rule. [6] openapi.yaml:47:5 at #/securityDefinitions/oauthApplication/authorizationUrl @@ -86,7 +86,7 @@ The field \`authorizationUrl\` is not allowed here. 48 | tokenUrl: 'http://tokenUrl' 49 | description: oauth application -Error was generated by the spec rule. +Error was generated by the struct rule. [7] openapi.yaml:56:5 at #/securityDefinitions/oauthPassword/authorizationUrl @@ -100,7 +100,7 @@ The field \`authorizationUrl\` is not allowed here. 57 | tokenUrl: 'http://tokenUrl' 58 | description: oauth password -Error was generated by the spec rule. +Error was generated by the struct rule. /openapi.yaml: validated in ms diff --git a/__tests__/lint/operation-security-scheme-oas3-error/snapshot.js b/__tests__/lint/operation-security-scheme-oas3-error/snapshot.js index ad9b05a0af..bde1116bac 100644 --- a/__tests__/lint/operation-security-scheme-oas3-error/snapshot.js +++ b/__tests__/lint/operation-security-scheme-oas3-error/snapshot.js @@ -14,7 +14,7 @@ Property \`testProp\` is not expected here. 36 | tokenUrl: 'http://tokenUrl' 37 | scopes: -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:36:11 at #/components/securitySchemes/petstore_auth/flows/implicit/tokenUrl @@ -28,7 +28,7 @@ Property \`tokenUrl\` is not expected here. 37 | scopes: 38 | 'write:pets': modify pets in your account -Error was generated by the spec rule. +Error was generated by the struct rule. [3] openapi.yaml:41:11 at #/components/securitySchemes/petstore_auth/flows/password/authorizationUrl @@ -42,7 +42,7 @@ Property \`authorizationUrl\` is not expected here. 42 | tokenUrl: 'http://tokenUrl' 43 | scopes: -Error was generated by the spec rule. +Error was generated by the struct rule. [4] openapi.yaml:51:7 at #/components/securitySchemes/api_key/authorizationUrl @@ -56,7 +56,7 @@ Property \`authorizationUrl\` is not expected here. 52 | httpScheme: 53 | type: http -Error was generated by the spec rule. +Error was generated by the struct rule. [5] openapi.yaml:54:7 at #/components/securitySchemes/httpScheme/name @@ -70,7 +70,7 @@ The field \`name\` is not allowed here. 55 | in: header 56 | scheme: scheme -Error was generated by the spec rule. +Error was generated by the struct rule. [6] openapi.yaml:55:7 at #/components/securitySchemes/httpScheme/in @@ -84,7 +84,7 @@ The field \`in\` is not allowed here. 56 | scheme: scheme 57 | description: http scheme -Error was generated by the spec rule. +Error was generated by the struct rule. [7] openapi.yaml:58:7 at #/components/securitySchemes/httpScheme/authorizationUrl @@ -97,7 +97,7 @@ Property \`authorizationUrl\` is not expected here. | ^^^^^^^^^^^^^^^^ 59 | -Error was generated by the spec rule. +Error was generated by the struct rule. [8] openapi.yaml:18:5 at #/paths/~1pet~1findByStatus/get diff --git a/__tests__/lint/spec-error-if-minimum-not-correct/redocly.yaml b/__tests__/lint/spec-error-if-minimum-not-correct/redocly.yaml index 2abdf31d93..2a5a25db6f 100644 --- a/__tests__/lint/spec-error-if-minimum-not-correct/redocly.yaml +++ b/__tests__/lint/spec-error-if-minimum-not-correct/redocly.yaml @@ -3,6 +3,6 @@ apis: root: ./openapi.yaml rules: - spec: error + struct: error extends: [recommended] diff --git a/__tests__/lint/spec-error-if-minimum-not-correct/snapshot.js b/__tests__/lint/spec-error-if-minimum-not-correct/snapshot.js index fcbfdf0a06..aa82b64769 100644 --- a/__tests__/lint/spec-error-if-minimum-not-correct/snapshot.js +++ b/__tests__/lint/spec-error-if-minimum-not-correct/snapshot.js @@ -14,7 +14,7 @@ The value of the minItems field must be greater than or equal to 0 30 | maxItems: -3 31 | maxLength: -4 -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:30:23 at #/paths/~1pet~1findByStatus/get/parameters/0/schema/maxItems @@ -28,7 +28,7 @@ The value of the maxItems field must be greater than or equal to 0 31 | maxLength: -4 32 | minLength: -2 -Error was generated by the spec rule. +Error was generated by the struct rule. [3] openapi.yaml:31:24 at #/paths/~1pet~1findByStatus/get/parameters/0/schema/maxLength @@ -42,7 +42,7 @@ The value of the maxLength field must be greater than or equal to 0 32 | minLength: -2 33 | items: -Error was generated by the spec rule. +Error was generated by the struct rule. [4] openapi.yaml:32:24 at #/paths/~1pet~1findByStatus/get/parameters/0/schema/minLength @@ -56,7 +56,7 @@ The value of the minLength field must be greater than or equal to 0 33 | items: 34 | type: string -Error was generated by the spec rule. +Error was generated by the struct rule. [5] openapi.yaml:69:27 at #/components/schemas/Dog/allOf/0/properties/packSize/multipleOf @@ -70,7 +70,7 @@ The value of the multipleOf field must be greater than or equal to 0 70 | maxProperties: -3 71 | minProperties: -8 -Error was generated by the spec rule. +Error was generated by the struct rule. [6] openapi.yaml:70:30 at #/components/schemas/Dog/allOf/0/properties/packSize/maxProperties @@ -84,7 +84,7 @@ The value of the maxProperties field must be greater than or equal to 0 71 | minProperties: -8 72 | required: -Error was generated by the spec rule. +Error was generated by the struct rule. [7] openapi.yaml:71:30 at #/components/schemas/Dog/allOf/0/properties/packSize/minProperties @@ -98,7 +98,7 @@ The value of the minProperties field must be greater than or equal to 0 72 | required: 73 | - packSize -Error was generated by the spec rule. +Error was generated by the struct rule. [8] openapi.yaml:15:5 at #/paths/~1pet~1findByStatus/get diff --git a/__tests__/lint/spec-from/redocly.yaml b/__tests__/lint/spec-from/redocly.yaml index ce11a2ddb6..b90b58d24e 100644 --- a/__tests__/lint/spec-from/redocly.yaml +++ b/__tests__/lint/spec-from/redocly.yaml @@ -3,4 +3,4 @@ apis: root: ./openapi.yaml rules: - spec: error + struct: error diff --git a/__tests__/lint/spec-from/snapshot.js b/__tests__/lint/spec-from/snapshot.js index 961d45a289..c180b35796 100644 --- a/__tests__/lint/spec-from/snapshot.js +++ b/__tests__/lint/spec-from/snapshot.js @@ -16,7 +16,7 @@ The field \`paths\` must be present on this level. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 14 | -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:1:1 at #/ @@ -32,7 +32,7 @@ The field \`info\` must be present on this level. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 14 | -Error was generated by the spec rule. +Error was generated by the struct rule. [3] openapi.yaml:5:7 at #/components/requestBodies/TestRequestBody/content @@ -48,7 +48,7 @@ Property \`content\` is not expected here. referenced from openapi.yaml:13:11 at #/components/schemas/TestSchema/allOf/0 -Error was generated by the spec rule. +Error was generated by the struct rule. /openapi.yaml: validated in ms diff --git a/__tests__/lint/spec-json-schema-validation-dependentRequired/redocly.yaml b/__tests__/lint/spec-json-schema-validation-dependentRequired/redocly.yaml index 9867f7c464..6b3519e830 100644 --- a/__tests__/lint/spec-json-schema-validation-dependentRequired/redocly.yaml +++ b/__tests__/lint/spec-json-schema-validation-dependentRequired/redocly.yaml @@ -3,5 +3,5 @@ apis: root: ./openapi.yaml rules: - spec: error + struct: error no-invalid-media-type-examples: error diff --git a/__tests__/lint/wrong-required-type/redocly.yaml b/__tests__/lint/wrong-required-type/redocly.yaml index 6fd05e2217..1ef2b32fd2 100644 --- a/__tests__/lint/wrong-required-type/redocly.yaml +++ b/__tests__/lint/wrong-required-type/redocly.yaml @@ -3,5 +3,5 @@ apis: root: ./openapi.yaml rules: - spec: error + struct: error required-string-property-missing-min-length: error diff --git a/__tests__/lint/wrong-required-type/snapshot.js b/__tests__/lint/wrong-required-type/snapshot.js index aa5bdb0d14..3b94859405 100644 --- a/__tests__/lint/wrong-required-type/snapshot.js +++ b/__tests__/lint/wrong-required-type/snapshot.js @@ -13,7 +13,7 @@ Expected type \`array\` but got \`boolean\`. | ^^^^ 13 | -Error was generated by the spec rule. +Error was generated by the struct rule. /openapi.yaml: validated in ms diff --git a/__tests__/zero-config/default-recommended-fallback/snapshot.js b/__tests__/zero-config/default-recommended-fallback/snapshot.js index d02a182f31..cf8e9fef36 100644 --- a/__tests__/zero-config/default-recommended-fallback/snapshot.js +++ b/__tests__/zero-config/default-recommended-fallback/snapshot.js @@ -16,7 +16,7 @@ Property \`testProp\` is not expected here. 36 | tokenUrl: 'http://tokenUrl' 37 | scopes: -Error was generated by the spec rule. +Error was generated by the struct rule. [2] openapi.yaml:36:11 at #/components/securitySchemes/petstore_auth/flows/implicit/tokenUrl @@ -30,7 +30,7 @@ Property \`tokenUrl\` is not expected here. 37 | scopes: 38 | 'write:pets': modify pets in your account -Error was generated by the spec rule. +Error was generated by the struct rule. [3] openapi.yaml:41:11 at #/components/securitySchemes/petstore_auth/flows/password/authorizationUrl @@ -44,7 +44,7 @@ Property \`authorizationUrl\` is not expected here. 42 | tokenUrl: 'http://tokenUrl' 43 | scopes: -Error was generated by the spec rule. +Error was generated by the struct rule. [4] openapi.yaml:51:7 at #/components/securitySchemes/api_key/authorizationUrl @@ -58,7 +58,7 @@ Property \`authorizationUrl\` is not expected here. 52 | httpScheme: 53 | type: http -Error was generated by the spec rule. +Error was generated by the struct rule. [5] openapi.yaml:54:7 at #/components/securitySchemes/httpScheme/name @@ -72,7 +72,7 @@ The field \`name\` is not allowed here. 55 | in: header 56 | scheme: scheme -Error was generated by the spec rule. +Error was generated by the struct rule. [6] openapi.yaml:55:7 at #/components/securitySchemes/httpScheme/in @@ -86,7 +86,7 @@ The field \`in\` is not allowed here. 56 | scheme: scheme 57 | description: http scheme -Error was generated by the spec rule. +Error was generated by the struct rule. [7] openapi.yaml:58:7 at #/components/securitySchemes/httpScheme/authorizationUrl @@ -99,7 +99,7 @@ Property \`authorizationUrl\` is not expected here. | ^^^^^^^^^^^^^^^^ 59 | -Error was generated by the spec rule. +Error was generated by the struct rule. [8] openapi.yaml:18:5 at #/paths/~1pet~1findByStatus/get diff --git a/docs/changelog.md b/docs/changelog.md index 7f30bc5dc7..20f9b28c0e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -677,7 +677,7 @@ No code changes. ### Features -- Added the [required-min-length-string-type-property](./rules/required-string-property-missing-min-length.md) rule that requires required properties in the API description with type `string` to have a `minLength`. +- Added the [required-min-length-string-type-property](./rules/oas/required-string-property-missing-min-length.md) rule that requires required properties in the API description with type `string` to have a `minLength`. ### Fixes @@ -709,7 +709,7 @@ No code changes. ### Features - Added custom output file option to the `join` command. -- Added an option to include webhooks to [operation-4xx-response](./rules/operation-4xx-response.md) rule. +- Added an option to include webhooks to [operation-4xx-response](./rules/oas/operation-4xx-response.md) rule. - Added a new built-in decorator [info-override](./decorators/info-override.md). - Added support for `/` as a separator which puts paths into subdirectories for each path segment with the [split command](./commands/split.md). @@ -852,7 +852,7 @@ theme: - Added rfc7807 problem details rule. - Improved error messages by adding `referenced from` information. -- Added the [`spec-components-invalid-map-name`](./rules/spec-components-invalid-map-name.md) rule for component map names validation. +- Added the [`spec-components-invalid-map-name`](./rules/oas/spec-components-invalid-map-name.md) rule for component map names validation. - Added a new lint `--format` option: `summary`. ### Fixes @@ -1272,8 +1272,8 @@ rules: - Added support for the [region](./configuration/index.md) option with the `login`, `push`, and other commands. - Added two new built-in rules: - - [no-invalid-schema-examples](./rules/no-invalid-schema-examples.md) - - [no-invalid-parameter-examples](./rules/no-invalid-parameter-examples.md) + - [no-invalid-schema-examples](./rules/oas/no-invalid-schema-examples.md) + - [no-invalid-parameter-examples](./rules/oas/no-invalid-parameter-examples.md) ### Fixes @@ -1306,7 +1306,7 @@ rules: ### Features -- Added a new built-in rule: [operation-4xx-response](./rules/operation-4xx-response.md). +- Added a new built-in rule: [operation-4xx-response](./rules/oas/operation-4xx-response.md). --- @@ -1315,11 +1315,10 @@ rules: ### Features - Added five new built-in rules: - - [path-excludes-patterns](./rules/path-excludes-patterns.md) - - [no-http-verbs-in-paths](./rules/no-http-verbs-in-paths.md) - - [path-excludes-patterns](./rules/path-excludes-patterns.md) - - [request-mime-type](./rules/request-mime-type.md) - - [response-mime-type](./rules/response-mime-type.md) + - [path-excludes-patterns](./rules/oas/path-excludes-patterns.md) + - [no-http-verbs-in-paths](./rules/oas/no-http-verbs-in-paths.md) + - [request-mime-type](./rules/oas/request-mime-type.md) + - [response-mime-type](./rules/oas/response-mime-type.md) ### Fixes diff --git a/docs/configuration/reference/rules.md b/docs/configuration/reference/rules.md index 94128c469e..ca024fe411 100644 --- a/docs/configuration/reference/rules.md +++ b/docs/configuration/reference/rules.md @@ -40,7 +40,7 @@ The `rules` block can be used at the root of a configuration file, or inside an - {additional properties} - any -- Some rules allow additional configuration, check the details of each rule to find out the values that can be supplied here. For example the [`boolean-parameter-prefixes` rule](../../rules/boolean-parameter-prefixes.md) supports an additional option of `prefixes` that accepts an array of strings. +- Some rules allow additional configuration, check the details of each rule to find out the values that can be supplied here. For example the [`boolean-parameter-prefixes` rule](../../rules/oas/boolean-parameter-prefixes.md) supports an additional option of `prefixes` that accepts an array of strings. {% /table %} diff --git a/docs/configuration/rules.md b/docs/configuration/rules.md index 8b0f9c0400..1b9cd2e402 100644 --- a/docs/configuration/rules.md +++ b/docs/configuration/rules.md @@ -27,7 +27,7 @@ Find a full list of [built-in rules here](../rules/built-in-rules.md). ## Set rule options -Some rules allow additional configuration. For example, the rule `boolean-parameter-prefixes` supports an array of prefixes ([see rule documentation](../rules/boolean-parameter-prefixes.md)). To set these in a configuration file, set the rule `severity` and any options within the rule configuration, like this: +Some rules allow additional configuration. For example, the rule `boolean-parameter-prefixes` supports an array of prefixes ([see rule documentation](../rules/oas/boolean-parameter-prefixes.md)). To set these in a configuration file, set the rule `severity` and any options within the rule configuration, like this: ```yaml rules: diff --git a/docs/decorators/remove-unused-components.md b/docs/decorators/remove-unused-components.md index 0acde4f05a..39f24478de 100644 --- a/docs/decorators/remove-unused-components.md +++ b/docs/decorators/remove-unused-components.md @@ -21,7 +21,7 @@ decorators: ## Examples -Read the article on [no-unused-components](../rules/no-unused-components.md#examples) rule to see examples. +Read the article on [no-unused-components](../rules/oas/no-unused-components.md#examples) rule to see examples. ## Related decorators diff --git a/docs/guides/response-contains-property.md b/docs/guides/response-contains-property.md index f44786fc5c..012c0db7d9 100644 --- a/docs/guides/response-contains-property.md +++ b/docs/guides/response-contains-property.md @@ -6,7 +6,7 @@ tocMaxDepth: 3 ## Overview -This guide describes how to ensure that the API operation's response [contains a specific property](../rules/response-contains-property.md) +This guide describes how to ensure that the API operation's response [contains a specific property](../rules/oas/response-contains-property.md) with three different cases: 1. Single response containing one property diff --git a/docs/rules/async/channels-kebab-case.md b/docs/rules/async/channels-kebab-case.md new file mode 100644 index 0000000000..84be0f4b13 --- /dev/null +++ b/docs/rules/async/channels-kebab-case.md @@ -0,0 +1,78 @@ +# channels-kebab-case + +Channel address should be `kebab-case` (lowercase with hyphens). + +| AsyncAPI | Compatibility | +| -------- | ------------- | +| 2.6 | ✅ | +| 3.0 | ✅ | + +## API design principles + +Using consistent casing for the channel address provides a better developer experience and a more predictable experience overall. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + channels-kebab-case: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + channels-kebab-case: error +``` + +Example of an **incorrect** channel: + +```yaml +channels: + ticketSales: + address: transactions/ticketSales # channel address value checked by rule + messages: + ticketSaleTransaction: + $ref: '#/components/messages/ticketSaleTransaction' +``` + +Example of a **correct** channel: + +```yaml +channels: + ticketSales: + address: transactions/ticket-sales # channel address value checked by rule + messages: + ticketSaleTransaction: + $ref: '#/components/messages/ticketSaleTransaction' +``` + +### Channel rules for AsyncAPI 2.6 + +The syntax for how the channels are described changed with the AsyncAPI 3.0 release. + +If you still AsyncAPI 2.6, this rule works, and checks the channel address used as the key of the `channels` object. +For example, the rule would catch this example where `transactions/ticketSales` is used as a channel name: + +```yaml +channels: + transactions/ticketSales: # channel address value checked by rule + subscribe: + message: + $ref: '#/components/messages/ticketSaleTransaction' +``` + +Change the channel name to `transactions/ticket-sales` to comply with this rule. + +## Resources + +- [Rule source async3](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/async3/channels-kebab-case.ts) +- [Rule source async2](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/async2/channels-kebab-case.ts) diff --git a/docs/rules/async/no-channel-trailing-slash.md b/docs/rules/async/no-channel-trailing-slash.md new file mode 100644 index 0000000000..49804e5a53 --- /dev/null +++ b/docs/rules/async/no-channel-trailing-slash.md @@ -0,0 +1,80 @@ +# no-channel-trailing-slash + +Channel names must not have trailing slashes in their address. + +| AsyncAPI | Compatibility | +| -------- | ------------- | +| 2.6 | ✅ | +| 3.0 | ✅ | + +## API design principles + +Depending on the protocol, the trailing slash may indicate an error or simple inconsistency between channels or documentation. +Enable this rule to make sure that no channel address includes the trailing slash. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + no-channel-trailing-slash: error + +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + no-channel-trailing-slash: error +``` + +Example of an **incorrect** channel: + +```yaml +channels: + channel1: + address: events/trailing/ + messages: + event1: + $ref: '#/components/messages/event1' +``` + +Example of a **correct** channel: + +```yaml +channels: + channel1: + address: events/expected + messages: + event1: + $ref: '#/components/messages/event1' +``` + +### Channel rules for AsyncAPI 2.6 + +The syntax for how the channels are described changed with the AsyncAPI 3.0 release. + +This rule also works with AsyncAPI 2.6, and checks the channel address used as the key of the `channels` object. +For example, the rule produces an error when it sees this channel with a trailing slash: + +```yaml +channels: + events/trailing/: # channel address value checked by rule + subscribe: + message: + $ref: '#/components/messages/event1' +``` + +Change the channel name to `events/expected` (or another value without a trailing slash) to comply with this rule. + +## Resources + +- [Rule source async3](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/async3/no-channel-trailing-slash.ts) +- [Rule source async2](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/async2/no-channel-trailing-slash.ts) diff --git a/docs/rules/built-in-rules.md b/docs/rules/built-in-rules.md index 93576ce6bb..246675ec60 100644 --- a/docs/rules/built-in-rules.md +++ b/docs/rules/built-in-rules.md @@ -19,77 +19,77 @@ Details of all the rules available "out of the box" with Redocly CLI are listed ### Special rules -- [no-unresolved-refs](./no-unresolved-refs.md): Every `$ref` must exist -- [no-unused-components](./no-unused-components.md): All components must be used -- [security-defined](./security-defined.md): Security rules must be defined, either globally or per-operation +- [no-unresolved-refs](./oas/no-unresolved-refs.md): Every `$ref` must exist +- [no-unused-components](./oas/no-unused-components.md): All components must be used +- [security-defined](./oas/security-defined.md): Security rules must be defined, either globally or per-operation - [spec](./spec.md): Conform to the declared OpenAPI specification version -- [spec-components-invalid-map-name](./spec-components-invalid-map-name.md): Use only alphanumeric and basic punctuation as key names in the components section -- [spec-strict-refs](./spec-strict-refs.md) Restricts the usage of the `$ref` keyword. +- [spec-components-invalid-map-name](./oas/spec-components-invalid-map-name.md): Use only alphanumeric and basic punctuation as key names in the components section +- [spec-strict-refs](./oas/spec-strict-refs.md) Restricts the usage of the `$ref` keyword. ### Info -- [info-contact](./info-contact.md): Contact section is defined under `info` -- [info-license](./info-license.md): License section is defined under `info` -- [info-license-url](./info-license-url.md): License section contains a `url` to the license +- [info-contact](./oas/info-contact.md): Contact section is defined under `info` +- [info-license](./oas/info-license.md): License section is defined under `info` +- [info-license-url](./oas/info-license-url.md): License section contains a `url` to the license ### Operations -- [operation-2xx-response](./operation-2xx-response.md): Every operation needs at least one 2xx response -- [operation-4xx-response](./operation-4xx-response.md): Every operation needs at least one 4xx response -- [operation-4xx-problem-details-rfc7807](./operation-4xx-problem-details-rfc7807.md): All 4xx responses use RFC7807 format -- [operation-description](./operation-description.md): Description field is required for every operation -- [operation-operationId](./operation-operationId.md): OperationId is required for every operation -- [operation-operationId-unique](./operation-operationId-unique.md): OperationId must be unique -- [operation-operationId-url-safe](./operation-operationId-url-safe.md): OperationIds can only contain characters that are safe to use in URLs -- [operation-summary](./operation-summary.md): Summary is required for every operation +- [operation-2xx-response](./oas/operation-2xx-response.md): Every operation needs at least one 2xx response +- [operation-4xx-response](./oas/operation-4xx-response.md): Every operation needs at least one 4xx response +- [operation-4xx-problem-details-rfc7807](./oas/operation-4xx-problem-details-rfc7807.md): All 4xx responses use RFC7807 format +- [operation-description](./oas/operation-description.md): Description field is required for every operation +- [operation-operationId](./oas/operation-operationId.md): OperationId is required for every operation +- [operation-operationId-unique](./oas/operation-operationId-unique.md): OperationId must be unique +- [operation-operationId-url-safe](./oas/operation-operationId-url-safe.md): OperationIds can only contain characters that are safe to use in URLs +- [operation-summary](./oas/operation-summary.md): Summary is required for every operation ### Parameters -- [boolean-parameter-prefixes](./boolean-parameter-prefixes.md): All boolean paramater names start with a particular prefix (such as "is") -- [no-invalid-parameter-examples](./no-invalid-parameter-examples.md): Parameter examples must match declared schema types -- [operation-parameters-unique](./operation-parameters-unique.md): No repeated parameter names within an operation -- [parameter-description](./parameter-description.md): Parameters must all have descriptions -- [path-declaration-must-exist](./path-declaration-must-exist.md): Paths must define template variables where placeholders are needed -- [path-not-include-query](./path-not-include-query.md): No query parameters in path declarations (declare them as parameters with `in: query`) -- [path-parameters-defined](./path-parameters-defined.md): Path template variables must be defined as parameters +- [boolean-parameter-prefixes](./oas/boolean-parameter-prefixes.md): All boolean paramater names start with a particular prefix (such as "is") +- [no-invalid-parameter-examples](./oas/no-invalid-parameter-examples.md): Parameter examples must match declared schema types +- [operation-parameters-unique](./oas/operation-parameters-unique.md): No repeated parameter names within an operation +- [parameter-description](./oas/parameter-description.md): Parameters must all have descriptions +- [path-declaration-must-exist](./oas/path-declaration-must-exist.md): Paths must define template variables where placeholders are needed +- [path-not-include-query](./oas/path-not-include-query.md): No query parameters in path declarations (declare them as parameters with `in: query`) +- [path-parameters-defined](./oas/path-parameters-defined.md): Path template variables must be defined as parameters ### Paths -- [no-ambiguous-paths](./no-ambiguous-paths.md): No path can match more than one PathItem entry, including template variables -- [no-http-verbs-in-paths](./no-http-verbs-in-paths.md): Verbs like "get" cannot be used in paths -- [no-identical-paths](./no-identical-paths.md): Paths cannot be identical, including template variables -- [no-path-trailing-slash](./no-path-trailing-slash.md): No trailing slashes on paths -- [path-excludes-patterns](./path-excludes-patterns.md): Set a regular expression that cannot be used in paths -- [path-segment-plural](./path-segment-plural.md): All URL segments in a path must be plural (exceptions can be configured) -- [paths-kebab-case](./paths-kebab-case.md): Paths must be in `kebab-case` format +- [no-ambiguous-paths](./oas/no-ambiguous-paths.md): No path can match more than one PathItem entry, including template variables +- [no-http-verbs-in-paths](./oas/no-http-verbs-in-paths.md): Verbs like "get" cannot be used in paths +- [no-identical-paths](./oas/no-identical-paths.md): Paths cannot be identical, including template variables +- [no-path-trailing-slash](./oas/no-path-trailing-slash.md): No trailing slashes on paths +- [path-excludes-patterns](./oas/path-excludes-patterns.md): Set a regular expression that cannot be used in paths +- [path-segment-plural](./oas/path-segment-plural.md): All URL segments in a path must be plural (exceptions can be configured) +- [paths-kebab-case](./oas/paths-kebab-case.md): Paths must be in `kebab-case` format ### Requests, Responses, and Schemas -- [no-enum-type-mismatch](./no-enum-type-mismatch.md): Enum options must match the data type declared in the schema -- [no-example-value-and-externalValue](./no-example-value-and-externalValue.md): Either the `value` or `externalValue` may be present, but not both -- [no-invalid-media-type-examples](./no-invalid-media-type-examples.md): Example request bodies must match the declared schema -- [no-invalid-schema-examples](./no-invalid-schema-examples.md): Schema examples must match declared types -- [request-mime-type](./request-mime-type.md): Configure allowed mime types for requests -- [response-mime-type](./response-mime-type.md): Configure allowed mime types for responses -- [response-contains-header](./response-contains-header.md): List headers that must be included with specific response types -- [response-contains-property](./response-contains-property.md): Specify properties that should be present in specific response types -- [scalar-property-missing-example](./scalar-property-missing-example.md): All required scalar (non-object) properties must have examples defined -- [required-string-property-missing-min-length](./required-string-property-missing-min-length.md): All required properties of type string must have a `minLength` configured +- [no-enum-type-mismatch](./oas/no-enum-type-mismatch.md): Enum options must match the data type declared in the schema +- [no-example-value-and-externalValue](./oas/no-example-value-and-externalValue.md): Either the `value` or `externalValue` may be present, but not both +- [no-invalid-media-type-examples](./oas/no-invalid-media-type-examples.md): Example request bodies must match the declared schema +- [no-invalid-schema-examples](./oas/no-invalid-schema-examples.md): Schema examples must match declared types +- [request-mime-type](./oas/request-mime-type.md): Configure allowed mime types for requests +- [response-mime-type](./oas/response-mime-type.md): Configure allowed mime types for responses +- [response-contains-header](./oas/response-contains-header.md): List headers that must be included with specific response types +- [response-contains-property](./oas/response-contains-property.md): Specify properties that should be present in specific response types +- [scalar-property-missing-example](./oas/scalar-property-missing-example.md): All required scalar (non-object) properties must have examples defined +- [required-string-property-missing-min-length](./oas/required-string-property-missing-min-length.md): All required properties of type string must have a `minLength` configured ### Servers -- [no-empty-servers](./no-empty-servers.md): Servers array must be defined -- [no-server-example.com](./no-server-example-com.md): `example.com` is not acceptable as a server URL -- [no-server-trailing-slash](./no-server-trailing-slash.md): Server URLs cannot end with a slash (paths usually start with a slash) -- [no-server-variables-empty-enum](./no-server-variables-empty-enum.md): Require that enum values are set if variables are used in server definition -- [no-undefined-server-variable](./no-undefined-server-variable.md): All variables in server definition must be defined +- [no-empty-servers](./oas/no-empty-servers.md): Servers array must be defined +- [no-server-example.com](./oas/no-server-example-com.md): `example.com` is not acceptable as a server URL +- [no-server-trailing-slash](./oas/no-server-trailing-slash.md): Server URLs cannot end with a slash (paths usually start with a slash) +- [no-server-variables-empty-enum](./oas/no-server-variables-empty-enum.md): Require that enum values are set if variables are used in server definition +- [no-undefined-server-variable](./oas/no-undefined-server-variable.md): All variables in server definition must be defined ### Tags -- [operation-singular-tag](./operation-singular-tag.md): Each operation may only have one tag -- [operation-tag-defined](./operation-tag-defined.md): Tags can only be used if they are defined at the top level -- [tag-description](./tag-description.md): Tags must have descriptions -- [tags-alphabetical](./tags-alphabetical.md): Tags in the top-level `tags` section must appear alphabetically +- [operation-singular-tag](./oas/operation-singular-tag.md): Each operation may only have one tag +- [operation-tag-defined](./oas/operation-tag-defined.md): Tags can only be used if they are defined at the top level +- [tag-description](./oas/tag-description.md): Tags must have descriptions +- [tags-alphabetical](./oas/tags-alphabetical.md): Tags in the top-level `tags` section must appear alphabetically ## Rule configuration syntax diff --git a/docs/rules/minimal.md b/docs/rules/minimal.md index bbc49fddbb..aef0c75e80 100644 --- a/docs/rules/minimal.md +++ b/docs/rules/minimal.md @@ -8,33 +8,33 @@ The rules contained in the minimal ruleset: Errors: -- [no-server-trailing-slash](./no-server-trailing-slash.md) -- [no-server-variables-empty-enum](./no-server-variables-empty-enum.md) -- [no-unresolved-refs](./no-unresolved-refs.md) +- [no-server-trailing-slash](./oas/no-server-trailing-slash.md) +- [no-server-variables-empty-enum](./oas/no-server-variables-empty-enum.md) +- [no-unresolved-refs](./oas/no-unresolved-refs.md) - [spec](./spec.md) Warnings: - [configurable rules](./configurable-rules.md) -- [no-ambiguous-paths](./no-ambiguous-paths.md) -- [no-empty-servers](./no-empty-servers.md) -- [no-enum-type-mismatch](./no-enum-type-mismatch.md) -- [no-example-value-and-externalValue](./no-example-value-and-externalValue.md) -- [no-identical-paths](./no-identical-paths.md) -- [no-invalid-media-type-examples](./no-invalid-media-type-examples.md) -- [no-path-trailing-slash](./no-path-trailing-slash.md) -- [no-server-example.com](./no-server-example-com.md) -- [no-undefined-server-variable](./no-undefined-server-variable.md) -- [no-unused-components](./no-unused-components.md) -- [operation-2xx-response](./operation-2xx-response.md) -- [operation-operationId-unique](./operation-operationId-unique.md) -- [operation-operationId-url-safe](./operation-operationId-url-safe.md) -- [operation-operationId](./operation-operationId.md) -- [operation-parameters-unique](./operation-parameters-unique.md) -- [operation-summary](./operation-summary.md) -- [path-declaration-must-exist](./path-declaration-must-exist.md) -- [path-not-include-query](./path-not-include-query.md) -- [path-parameters-defined](./path-parameters-defined.md) -- [security-defined](./security-defined.md) -- [spec-components-invalid-map-name](./spec-components-invalid-map-name.md) -- [tag-description](./tag-description.md) +- [no-ambiguous-paths](./oas/no-ambiguous-paths.md) +- [no-empty-servers](./oas/no-empty-servers.md) +- [no-enum-type-mismatch](./oas/no-enum-type-mismatch.md) +- [no-example-value-and-externalValue](./oas/no-example-value-and-externalValue.md) +- [no-identical-paths](./oas/no-identical-paths.md) +- [no-invalid-media-type-examples](./oas/no-invalid-media-type-examples.md) +- [no-path-trailing-slash](./oas/no-path-trailing-slash.md) +- [no-server-example.com](./oas/no-server-example-com.md) +- [no-undefined-server-variable](./oas/no-undefined-server-variable.md) +- [no-unused-components](./oas/no-unused-components.md) +- [operation-2xx-response](./oas/operation-2xx-response.md) +- [operation-operationId-unique](./oas/operation-operationId-unique.md) +- [operation-operationId-url-safe](./oas/operation-operationId-url-safe.md) +- [operation-operationId](./oas/operation-operationId.md) +- [operation-parameters-unique](./oas/operation-parameters-unique.md) +- [operation-summary](./oas/operation-summary.md) +- [path-declaration-must-exist](./oas/path-declaration-must-exist.md) +- [path-not-include-query](./oas/path-not-include-query.md)d +- [path-parameters-defined](./oas/path-parameters-defined.md) +- [security-defined](./oas/security-defined.md) +- [spec-components-invalid-map-name](./oas/spec-components-invalid-map-name.md) +- [tag-description](./oas/tag-description.md) diff --git a/docs/rules/array-parameter-serialization.md b/docs/rules/oas/array-parameter-serialization.md similarity index 96% rename from docs/rules/array-parameter-serialization.md rename to docs/rules/oas/array-parameter-serialization.md index 8c0226060e..ed1f4c5715 100644 --- a/docs/rules/array-parameter-serialization.md +++ b/docs/rules/oas/array-parameter-serialization.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/array-parameter-serialization +slug: /docs/cli/rules/oas/array-parameter-serialization --- # array-parameter-serialization @@ -97,7 +97,7 @@ paths: ## Related rules -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [boolean-parameter-prefixes](./boolean-parameter-prefixes.md) - [no-invalid-parameter-examples](./no-invalid-parameter-examples.md) - [parameter-description](./parameter-description.md) diff --git a/docs/rules/boolean-parameter-prefixes.md b/docs/rules/oas/boolean-parameter-prefixes.md similarity index 96% rename from docs/rules/boolean-parameter-prefixes.md rename to docs/rules/oas/boolean-parameter-prefixes.md index 9747995e4e..30cfe5858c 100644 --- a/docs/rules/boolean-parameter-prefixes.md +++ b/docs/rules/oas/boolean-parameter-prefixes.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/boolean-parameter-prefixes +slug: /docs/cli/rules/oas/boolean-parameter-prefixes --- # boolean-parameter-prefixes @@ -96,7 +96,7 @@ schema: ## Related rules -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [no-invalid-parameter-examples](./no-invalid-parameter-examples.md) - [parameter-description](./parameter-description.md) - [operation-parameters-unique](./operation-parameters-unique.md) diff --git a/docs/rules/component-name-unique.md b/docs/rules/oas/component-name-unique.md similarity index 98% rename from docs/rules/component-name-unique.md rename to docs/rules/oas/component-name-unique.md index c0926d095f..215e76dcfd 100644 --- a/docs/rules/component-name-unique.md +++ b/docs/rules/oas/component-name-unique.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/component-name-unique +slug: /docs/cli/rules/oas/component-name-unique --- # component-name-unique diff --git a/docs/rules/info-contact.md b/docs/rules/oas/info-contact.md similarity index 93% rename from docs/rules/info-contact.md rename to docs/rules/oas/info-contact.md index c2217ade25..b8052f3f30 100644 --- a/docs/rules/info-contact.md +++ b/docs/rules/oas/info-contact.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/info-contact +slug: /docs/cli/rules/oas/info-contact --- # info-contact @@ -73,8 +73,8 @@ info: - [info-license](./info-license.md) - [info-license-url](./info-license-url.md) -- [spec](./spec.md) -- [configurable rules](./configurable-rules.md) +- [spec](../spec.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/info-license-url.md b/docs/rules/oas/info-license-url.md similarity index 97% rename from docs/rules/info-license-url.md rename to docs/rules/oas/info-license-url.md index 6576425b6f..902d441485 100644 --- a/docs/rules/info-license-url.md +++ b/docs/rules/oas/info-license-url.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/info-license-url +slug: /docs/cli/rules/oas/info-license-url --- # info-license-url diff --git a/docs/rules/info-license.md b/docs/rules/oas/info-license.md similarity index 97% rename from docs/rules/info-license.md rename to docs/rules/oas/info-license.md index 3844040377..bda9cb11b3 100644 --- a/docs/rules/info-license.md +++ b/docs/rules/oas/info-license.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/info-license +slug: /docs/cli/rules/oas/info-license --- # info-license diff --git a/docs/rules/no-ambiguous-paths.md b/docs/rules/oas/no-ambiguous-paths.md similarity index 98% rename from docs/rules/no-ambiguous-paths.md rename to docs/rules/oas/no-ambiguous-paths.md index 16a3271495..9478e2362f 100644 --- a/docs/rules/no-ambiguous-paths.md +++ b/docs/rules/oas/no-ambiguous-paths.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-ambiguous-paths/ +slug: /docs/cli/rules/oas/no-ambiguous-paths --- # no-ambiguous-paths diff --git a/docs/rules/no-empty-servers.md b/docs/rules/oas/no-empty-servers.md similarity index 97% rename from docs/rules/no-empty-servers.md rename to docs/rules/oas/no-empty-servers.md index 8a081723e0..2042a9989e 100644 --- a/docs/rules/no-empty-servers.md +++ b/docs/rules/oas/no-empty-servers.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-empty-servers +slug: /docs/cli/rules/oas/no-empty-servers --- # no-empty-servers diff --git a/docs/rules/no-enum-type-mismatch.md b/docs/rules/oas/no-enum-type-mismatch.md similarity index 96% rename from docs/rules/no-enum-type-mismatch.md rename to docs/rules/oas/no-enum-type-mismatch.md index 163527451f..fa93059921 100644 --- a/docs/rules/no-enum-type-mismatch.md +++ b/docs/rules/oas/no-enum-type-mismatch.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-enum-type-mismatch +slug: /docs/cli/rules/oas/no-enum-type-mismatch --- # no-enum-type-mismatch @@ -86,7 +86,7 @@ properties: ## Related rules -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [no-invalid-media-type-examples](./no-invalid-media-type-examples.md) - [no-invalid-parameter-examples](./no-invalid-parameter-examples.md) - [no-invalid-schema-examples](./no-invalid-schema-examples.md) diff --git a/docs/rules/no-example-value-and-externalValue.md b/docs/rules/oas/no-example-value-and-externalValue.md similarity index 95% rename from docs/rules/no-example-value-and-externalValue.md rename to docs/rules/oas/no-example-value-and-externalValue.md index 567074a2d8..cecc9bd2ce 100644 --- a/docs/rules/no-example-value-and-externalValue.md +++ b/docs/rules/oas/no-example-value-and-externalValue.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-example-value-and-externalValue +slug: /docs/cli/rules/oas/no-example-value-and-externalValue --- # no-example-value-and-externalValue @@ -97,8 +97,8 @@ requestBody: ## Related rules -- [configurable rules](./configurable-rules.md) -- [spec](./spec.md) +- [configurable rules](../configurable-rules.md) +- [spec](../spec.md) ## Resources diff --git a/docs/rules/no-http-verbs-in-paths.md b/docs/rules/oas/no-http-verbs-in-paths.md similarity index 96% rename from docs/rules/no-http-verbs-in-paths.md rename to docs/rules/oas/no-http-verbs-in-paths.md index b785b6b927..3b4cbef373 100644 --- a/docs/rules/no-http-verbs-in-paths.md +++ b/docs/rules/oas/no-http-verbs-in-paths.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-http-verbs-in-paths +slug: /docs/cli/rules/oas/no-http-verbs-in-paths --- # no-http-verbs-in-paths @@ -119,7 +119,7 @@ This last example wouldn't trigger an error because the casing doesn't split "ge ## Related rules -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [path-excludes-patterns](./path-excludes-patterns.md) ## Resources diff --git a/docs/rules/no-identical-paths.md b/docs/rules/oas/no-identical-paths.md similarity index 96% rename from docs/rules/no-identical-paths.md rename to docs/rules/oas/no-identical-paths.md index 730eec5235..fa5982de2b 100644 --- a/docs/rules/no-identical-paths.md +++ b/docs/rules/oas/no-identical-paths.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-identical-paths +slug: /docs/cli/rules/oas/no-identical-paths --- # no-identical-paths @@ -77,7 +77,7 @@ paths: ## Related rules - [no-ambiguous-paths](./no-ambiguous-paths.md) -- [spec](./spec.md) +- [spec](../spec.md) ## Resources diff --git a/docs/rules/no-invalid-media-type-examples.md b/docs/rules/oas/no-invalid-media-type-examples.md similarity index 98% rename from docs/rules/no-invalid-media-type-examples.md rename to docs/rules/oas/no-invalid-media-type-examples.md index bec98235fe..5637603247 100644 --- a/docs/rules/no-invalid-media-type-examples.md +++ b/docs/rules/oas/no-invalid-media-type-examples.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-invalid-media-type-examples +slug: /docs/cli/rules/oas/no-invalid-media-type-examples --- # no-invalid-media-type-examples diff --git a/docs/rules/no-invalid-parameter-examples.md b/docs/rules/oas/no-invalid-parameter-examples.md similarity index 97% rename from docs/rules/no-invalid-parameter-examples.md rename to docs/rules/oas/no-invalid-parameter-examples.md index 1a9df49dc2..1a21ac1138 100644 --- a/docs/rules/no-invalid-parameter-examples.md +++ b/docs/rules/oas/no-invalid-parameter-examples.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-invalid-parameter-examples +slug: /docs/cli/rules/oas/no-invalid-parameter-examples --- # no-invalid-parameter-examples diff --git a/docs/rules/no-invalid-schema-examples.md b/docs/rules/oas/no-invalid-schema-examples.md similarity index 97% rename from docs/rules/no-invalid-schema-examples.md rename to docs/rules/oas/no-invalid-schema-examples.md index 14c0d1040b..f1e4fabd4c 100644 --- a/docs/rules/no-invalid-schema-examples.md +++ b/docs/rules/oas/no-invalid-schema-examples.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-invalid-schema-examples +slug: /docs/cli/rules/oas/no-invalid-schema-examples --- # no-invalid-schema-examples diff --git a/docs/rules/no-path-trailing-slash.md b/docs/rules/oas/no-path-trailing-slash.md similarity index 97% rename from docs/rules/no-path-trailing-slash.md rename to docs/rules/oas/no-path-trailing-slash.md index c651619477..cc40e415ea 100644 --- a/docs/rules/no-path-trailing-slash.md +++ b/docs/rules/oas/no-path-trailing-slash.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-path-trailing-slash +slug: /docs/cli/rules/oas/no-path-trailing-slash --- # no-path-trailing-slash diff --git a/docs/rules/no-required-schema-properties-undefined.md b/docs/rules/oas/no-required-schema-properties-undefined.md similarity index 97% rename from docs/rules/no-required-schema-properties-undefined.md rename to docs/rules/oas/no-required-schema-properties-undefined.md index 37d113a132..2da0826acb 100644 --- a/docs/rules/no-required-schema-properties-undefined.md +++ b/docs/rules/oas/no-required-schema-properties-undefined.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-required-schema-properties-undefined +slug: /docs/cli/rules/oas/no-required-schema-properties-undefined --- # no-required-schema-properties-undefined diff --git a/docs/rules/no-server-example-com.md b/docs/rules/oas/no-server-example-com.md similarity index 97% rename from docs/rules/no-server-example-com.md rename to docs/rules/oas/no-server-example-com.md index c90c5158b3..bbbdca87ec 100644 --- a/docs/rules/no-server-example-com.md +++ b/docs/rules/oas/no-server-example-com.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-server-example-com +slug: /docs/cli/rules/oas/no-server-example-com --- # no-server-example.com diff --git a/docs/rules/no-server-trailing-slash.md b/docs/rules/oas/no-server-trailing-slash.md similarity index 97% rename from docs/rules/no-server-trailing-slash.md rename to docs/rules/oas/no-server-trailing-slash.md index c1a59e75a0..235a368b8b 100644 --- a/docs/rules/no-server-trailing-slash.md +++ b/docs/rules/oas/no-server-trailing-slash.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-server-trailing-slash +slug: /docs/cli/rules/oas/no-server-trailing-slash --- # no-server-trailing-slash diff --git a/docs/rules/no-server-variables-empty-enum.md b/docs/rules/oas/no-server-variables-empty-enum.md similarity index 97% rename from docs/rules/no-server-variables-empty-enum.md rename to docs/rules/oas/no-server-variables-empty-enum.md index 447f5af8b7..9afe9b3595 100644 --- a/docs/rules/no-server-variables-empty-enum.md +++ b/docs/rules/oas/no-server-variables-empty-enum.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-server-variables-empty-enum +slug: /docs/cli/rules/oas/no-server-variables-empty-enum --- # no-server-variables-empty-enum diff --git a/docs/rules/no-undefined-server-variable.md b/docs/rules/oas/no-undefined-server-variable.md similarity index 97% rename from docs/rules/no-undefined-server-variable.md rename to docs/rules/oas/no-undefined-server-variable.md index 795876af51..9cffaf9dc2 100644 --- a/docs/rules/no-undefined-server-variable.md +++ b/docs/rules/oas/no-undefined-server-variable.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-undefined-server-variable +slug: /docs/cli/rules/oas/no-undefined-server-variable --- # no-undefined-server-variable diff --git a/docs/rules/no-unresolved-refs.md b/docs/rules/oas/no-unresolved-refs.md similarity index 94% rename from docs/rules/no-unresolved-refs.md rename to docs/rules/oas/no-unresolved-refs.md index 044bc15221..0f01a33305 100644 --- a/docs/rules/no-unresolved-refs.md +++ b/docs/rules/oas/no-unresolved-refs.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-unresolved +slug: /docs/cli/rules/oas/no-unresolved-refs --- # no-unresolved-refs @@ -84,8 +84,8 @@ components: ## Related rules -- [spec](./spec.md) -- [configurable rules](./configurable-rules.md) +- [spec](../spec.md) +- [configurable rules](../configurable-rules.md) - [no-unused-components](./no-unused-components.md) ## Resources diff --git a/docs/rules/no-unused-components.md b/docs/rules/oas/no-unused-components.md similarity index 97% rename from docs/rules/no-unused-components.md rename to docs/rules/oas/no-unused-components.md index a48af7a03b..2f30328b1f 100644 --- a/docs/rules/no-unused-components.md +++ b/docs/rules/oas/no-unused-components.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/no-unused-components +slug: /docs/cli/rules/oas/no-unused-components --- # no-unused-components diff --git a/docs/rules/operation-2xx-response.md b/docs/rules/oas/operation-2xx-response.md similarity index 97% rename from docs/rules/operation-2xx-response.md rename to docs/rules/oas/operation-2xx-response.md index 37e02985d7..1fbfb826fa 100644 --- a/docs/rules/operation-2xx-response.md +++ b/docs/rules/oas/operation-2xx-response.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-2xx-response +slug: /docs/cli/rules/oas/operation-2xx-response --- # operation-2xx-response diff --git a/docs/rules/operation-4xx-problem-details-rfc7807.md b/docs/rules/oas/operation-4xx-problem-details-rfc7807.md similarity index 97% rename from docs/rules/operation-4xx-problem-details-rfc7807.md rename to docs/rules/oas/operation-4xx-problem-details-rfc7807.md index 1f2b14ae98..b3b99d7b3b 100644 --- a/docs/rules/operation-4xx-problem-details-rfc7807.md +++ b/docs/rules/oas/operation-4xx-problem-details-rfc7807.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-4xx-problem-details-rfc7807 +slug: /docs/cli/rules/oas/operation-4xx-problem-details-rfc7807 --- # operation-4xx-problem-details-rfc7807 diff --git a/docs/rules/operation-4xx-response.md b/docs/rules/oas/operation-4xx-response.md similarity index 97% rename from docs/rules/operation-4xx-response.md rename to docs/rules/oas/operation-4xx-response.md index f351925541..4e0527e0ce 100644 --- a/docs/rules/operation-4xx-response.md +++ b/docs/rules/oas/operation-4xx-response.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-4xx-response +slug: /docs/cli/rules/oas/operation-4xx-response --- # operation-4xx-response diff --git a/docs/rules/operation-description.md b/docs/rules/oas/operation-description.md similarity index 88% rename from docs/rules/operation-description.md rename to docs/rules/oas/operation-description.md index 7b78760b6c..ef0b6bbe45 100644 --- a/docs/rules/operation-description.md +++ b/docs/rules/oas/operation-description.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-description +slug: /docs/cli/rules/oas/operation-description --- # operation-description @@ -64,11 +64,11 @@ get: - [tag-description](./tag-description.md) - [parameter-description](./parameter-description.md) - [operation-summary](./operation-summary.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [operation-operationId](./operation-operationId.md) ## Resources - [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/common/operation-description.ts) -- Consider using [configurable rules](./configurable-rules.md) for more specific rules for operation descriptions such as minimum length and pattern enforcement. +- Consider using [configurable rules](../configurable-rules.md) for more specific rules for operation descriptions such as minimum length and pattern enforcement. - [Operation object docs](https://redocly.com/docs/openapi-visual-reference/operation/) diff --git a/docs/rules/operation-operationId-unique.md b/docs/rules/oas/operation-operationId-unique.md similarity index 87% rename from docs/rules/operation-operationId-unique.md rename to docs/rules/oas/operation-operationId-unique.md index d0924a5f9f..934a1b0f99 100644 --- a/docs/rules/operation-operationId-unique.md +++ b/docs/rules/oas/operation-operationId-unique.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-operationId-unique +slug: /docs/cli/rules/oas/operation-operationId-unique --- # operation-operationId-unique @@ -73,10 +73,10 @@ paths: - [operation-summary](./operation-summary.md) - [operation-operationId-url-safe](./operation-operationId-url-safe.md) - [operation-operationId](./operation-operationId.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources - [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/common/operation-operationId-unique.ts) - [Operation object docs](https://redocly.com/docs/openapi-visual-reference/operation/) -- Consider using [configurable rules](./configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. +- Consider using [configurable rules](../configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. diff --git a/docs/rules/operation-operationId-url-safe.md b/docs/rules/oas/operation-operationId-url-safe.md similarity index 86% rename from docs/rules/operation-operationId-url-safe.md rename to docs/rules/oas/operation-operationId-url-safe.md index 7c159b0dc0..1b8da139c9 100644 --- a/docs/rules/operation-operationId-url-safe.md +++ b/docs/rules/oas/operation-operationId-url-safe.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-operationId-url-safe +slug: /docs/cli/rules/oas/operation-operationId-url-safe --- # operation-operationId-url-safe @@ -67,10 +67,10 @@ paths: - [operation-summary](./operation-summary.md) - [operation-operationId-unique](./operation-operationId-unique.md) - [operation-operationId](./operation-operationId.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources - [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/common/operation-operationId-url-safe.ts) - [Operation object docs](https://redocly.com/docs/openapi-visual-reference/operation/) -- Consider using [configurable rules](./configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. +- Consider using [configurable rules](../configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. diff --git a/docs/rules/operation-operationId.md b/docs/rules/oas/operation-operationId.md similarity index 89% rename from docs/rules/operation-operationId.md rename to docs/rules/oas/operation-operationId.md index c0c3ab447e..79e741a0aa 100644 --- a/docs/rules/operation-operationId.md +++ b/docs/rules/oas/operation-operationId.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-operationId +slug: /docs/cli/rules/oas/operation-operationId --- # operation-operationId @@ -74,4 +74,4 @@ paths: - [OperationIds make good API design - Redocly Blog](https://redocly.com/blog/operationid-is-api-design/) - [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/common/operation-operationId.ts) - [Operation object docs](https://redocly.com/docs/openapi-visual-reference/operation/) -- Consider using [configurable rules](./configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. +- Consider using [configurable rules](../configurable-rules.md) for more specific rules for `operationId`s such as length, casing, and pattern enforcement. diff --git a/docs/rules/operation-parameters-unique.md b/docs/rules/oas/operation-parameters-unique.md similarity index 97% rename from docs/rules/operation-parameters-unique.md rename to docs/rules/oas/operation-parameters-unique.md index 9b75646016..1657155008 100644 --- a/docs/rules/operation-parameters-unique.md +++ b/docs/rules/oas/operation-parameters-unique.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-parameters-unique +slug: /docs/cli/rules/oas/operation-parameters-unique --- # operation-parameters-unique diff --git a/docs/rules/operation-singular-tag.md b/docs/rules/oas/operation-singular-tag.md similarity index 97% rename from docs/rules/operation-singular-tag.md rename to docs/rules/oas/operation-singular-tag.md index 530b560692..975eaeedb3 100644 --- a/docs/rules/operation-singular-tag.md +++ b/docs/rules/oas/operation-singular-tag.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-singular-tag +slug: /docs/cli/rules/oas/operation-singular-tag --- # operation-singular-tag diff --git a/docs/rules/operation-summary.md b/docs/rules/oas/operation-summary.md similarity index 94% rename from docs/rules/operation-summary.md rename to docs/rules/oas/operation-summary.md index 1fd3e92c67..04f7087b00 100644 --- a/docs/rules/operation-summary.md +++ b/docs/rules/oas/operation-summary.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-summary +slug: /docs/cli/rules/oas/operation-summary --- # operation-summary @@ -61,7 +61,7 @@ post: ## Related rules - [operation-description](./operation-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [operation-operationId-unique](./operation-operationId-unique.md) ## Resources diff --git a/docs/rules/operation-tag-defined.md b/docs/rules/oas/operation-tag-defined.md similarity index 95% rename from docs/rules/operation-tag-defined.md rename to docs/rules/oas/operation-tag-defined.md index 8698cc972b..1a16356a25 100644 --- a/docs/rules/operation-tag-defined.md +++ b/docs/rules/oas/operation-tag-defined.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/operation-tag-defined +slug: /docs/cli/rules/oas/operation-tag-defined --- # operation-tag-defined @@ -75,7 +75,7 @@ paths: - [operation-singular-tag](./operation-singular-tag.md) - [tags-alphabetical](./tags-alphabetical.md) - [tag-description](./tag-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/parameter-description.md b/docs/rules/oas/parameter-description.md similarity index 94% rename from docs/rules/parameter-description.md rename to docs/rules/oas/parameter-description.md index 96b47ade77..0db4e41c9c 100644 --- a/docs/rules/parameter-description.md +++ b/docs/rules/oas/parameter-description.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/parameter-description +slug: /docs/cli/rules/oas/parameter-description --- # parameter-description @@ -69,7 +69,7 @@ paths: - [tag-description](./tag-description.md) - [operation-description](./operation-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/path-declaration-must-exist.md b/docs/rules/oas/path-declaration-must-exist.md similarity index 94% rename from docs/rules/path-declaration-must-exist.md rename to docs/rules/oas/path-declaration-must-exist.md index 786a2eafb7..c381cb1fd8 100644 --- a/docs/rules/path-declaration-must-exist.md +++ b/docs/rules/oas/path-declaration-must-exist.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/path-declaration-must-exist +slug: /docs/cli/rules/oas/path-declaration-must-exist --- # path-declaration-must-exist @@ -65,7 +65,7 @@ paths: - [path-parameters-defined](./path-parameters-defined.md) - [path-excludes-patterns](./path-excludes-patterns.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/path-excludes-patterns.md b/docs/rules/oas/path-excludes-patterns.md similarity index 95% rename from docs/rules/path-excludes-patterns.md rename to docs/rules/oas/path-excludes-patterns.md index 448ecfe7e4..fd16a821a6 100644 --- a/docs/rules/path-excludes-patterns.md +++ b/docs/rules/oas/path-excludes-patterns.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/path-excludes-patterns +slug: /docs/cli/rules/oas/path-excludes-patterns --- # path-excludes-patterns @@ -78,7 +78,7 @@ paths: - [no-http-verbs-in-paths.md](./no-http-verbs-in-paths.md) - [paths-kebab-case](./paths-kebab-case.md) - [operation-description](./operation-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/path-not-include-query.md b/docs/rules/oas/path-not-include-query.md similarity index 94% rename from docs/rules/path-not-include-query.md rename to docs/rules/oas/path-not-include-query.md index e68ee6f116..e9fc3b4b25 100644 --- a/docs/rules/path-not-include-query.md +++ b/docs/rules/oas/path-not-include-query.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/path-not-include-query +slug: /docs/cli/rules/oas/path-not-include-query --- # path-not-include-query @@ -69,7 +69,7 @@ paths: ## Related rules - [path-parameters-defined](./path-parameters-defined.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/path-parameters-defined.md b/docs/rules/oas/path-parameters-defined.md similarity index 94% rename from docs/rules/path-parameters-defined.md rename to docs/rules/oas/path-parameters-defined.md index 492ed5f9d8..185baff4d2 100644 --- a/docs/rules/path-parameters-defined.md +++ b/docs/rules/oas/path-parameters-defined.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/path-parameters-defined +slug: /docs/cli/rules/oas/path-parameters-defined --- # path-parameters-defined @@ -68,7 +68,7 @@ paths: - [path-declaration-must-exist](./path-declaration-must-exist.md) - [path-excludes-patterns](./path-excludes-patterns.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/path-segment-plural.md b/docs/rules/oas/path-segment-plural.md similarity index 96% rename from docs/rules/path-segment-plural.md rename to docs/rules/oas/path-segment-plural.md index 4adc09d7cc..0e6c45dffd 100644 --- a/docs/rules/path-segment-plural.md +++ b/docs/rules/oas/path-segment-plural.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/path-segment-plural +slug: /docs/cli/rules/oas/path-segment-plural --- # path-segment-plural @@ -91,7 +91,7 @@ paths: - [path-excludes-patterns](./path-excludes-patterns.md) - [paths-kebab-case](./paths-kebab-case.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/paths-kebab-case.md b/docs/rules/oas/paths-kebab-case.md similarity index 95% rename from docs/rules/paths-kebab-case.md rename to docs/rules/oas/paths-kebab-case.md index b42efa07a3..ccefca1806 100644 --- a/docs/rules/paths-kebab-case.md +++ b/docs/rules/oas/paths-kebab-case.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/paths-kebab-case +slug: /docs/cli/rules/oas/paths-kebab-case --- # paths-kebab-case @@ -75,7 +75,7 @@ paths: - [path-excludes-patterns](./path-excludes-patterns.md) - [paths-segment-plural](./path-segment-plural.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/request-mime-type.md b/docs/rules/oas/request-mime-type.md similarity index 95% rename from docs/rules/request-mime-type.md rename to docs/rules/oas/request-mime-type.md index e693ead38f..618697b952 100644 --- a/docs/rules/request-mime-type.md +++ b/docs/rules/oas/request-mime-type.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/request-mine-type +slug: /docs/cli/rules/oas/request-mine-type --- # request-mime-type @@ -80,7 +80,7 @@ paths: ## Related rules - [response-mime-type](./response-mime-type.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/required-string-property-missing-min-length.md b/docs/rules/oas/required-string-property-missing-min-length.md similarity index 91% rename from docs/rules/required-string-property-missing-min-length.md rename to docs/rules/oas/required-string-property-missing-min-length.md index f539d37e27..bd67aef95f 100644 --- a/docs/rules/required-string-property-missing-min-length.md +++ b/docs/rules/oas/required-string-property-missing-min-length.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/required-string-property-missing-min-length +slug: /docs/cli/rules/oas/required-string-property-missing-min-length --- # required-string-property-missing-min-length @@ -19,7 +19,7 @@ The `minLength` keyword constrains string values. When a property of type `strin ## Configuration To configure the rule, add it to the `rules` object in your configuration file. -Set the desired [severity](../rules.md#severity-settings) for the rule. +Set the desired [severity](../../rules.md#severity-settings) for the rule. ```yaml rules: @@ -81,7 +81,7 @@ schemas: - [no-invalid-schema-examples](./no-invalid-schema-examples.md) - [response-contains-property](./response-contains-property.md) -- [Custom rules](./configurable-rules.md) +- [Custom rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/response-contains-header.md b/docs/rules/oas/response-contains-header.md similarity index 96% rename from docs/rules/response-contains-header.md rename to docs/rules/oas/response-contains-header.md index 2a8f9f230e..677cd7a763 100644 --- a/docs/rules/response-contains-header.md +++ b/docs/rules/oas/response-contains-header.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/response-contains-header +slug: /docs/cli/rules/oas/response-contains-header --- # response-contains-header @@ -95,7 +95,7 @@ paths: - [response-contains-property](./response-contains-property.md) - [response-mime-type](./response-mime-type.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/response-contains-property.md b/docs/rules/oas/response-contains-property.md similarity index 96% rename from docs/rules/response-contains-property.md rename to docs/rules/oas/response-contains-property.md index cf107df9d4..f12fdb7aa2 100644 --- a/docs/rules/response-contains-property.md +++ b/docs/rules/oas/response-contains-property.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/response-contains-property +slug: /docs/cli/rules/oas/response-contains-property --- # response-contains-property @@ -99,7 +99,7 @@ paths: - [response-contains-headers](./response-contains-header.md) - [response-mime-type](./response-mime-type.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/response-mime-type.md b/docs/rules/oas/response-mime-type.md similarity index 95% rename from docs/rules/response-mime-type.md rename to docs/rules/oas/response-mime-type.md index 51b02ade92..370705f44e 100644 --- a/docs/rules/response-mime-type.md +++ b/docs/rules/oas/response-mime-type.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/response-mime-type +slug: /docs/cli/rules/oas/response-mime-type --- # response-mime-type @@ -87,7 +87,7 @@ paths: ## Related rules - [request-mime-type](./request-mime-type.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/scalar-property-missing-example.md b/docs/rules/oas/scalar-property-missing-example.md similarity index 93% rename from docs/rules/scalar-property-missing-example.md rename to docs/rules/oas/scalar-property-missing-example.md index 561391f630..5c4f1c43a1 100644 --- a/docs/rules/scalar-property-missing-example.md +++ b/docs/rules/oas/scalar-property-missing-example.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/scalar-property-missing-example +slug: /docs/cli/rules/oas/scalar-property-missing-example --- # scalar-property-missing-example @@ -22,7 +22,7 @@ Providing examples for properties in your API description not only improves the ## Configuration To configure the rule, add it to the `rules` object in your configuration file. -Set the desired [severity](../rules.md#severity-settings) for the rule. +Set the desired [severity](../../rules.md#severity-settings) for the rule. ```yaml rules: @@ -82,7 +82,7 @@ schemas: - [no-invalid-media-type-examples](./no-invalid-media-type-examples.md) - [no-invalid-parameter-examples](./no-invalid-parameter-examples.md) - [no-invalid-schema-examples](./no-invalid-schema-examples.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/security-defined.md b/docs/rules/oas/security-defined.md similarity index 96% rename from docs/rules/security-defined.md rename to docs/rules/oas/security-defined.md index 16ef1ab553..8831419f1b 100644 --- a/docs/rules/security-defined.md +++ b/docs/rules/oas/security-defined.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/security-defined +slug: /docs/cli/rules/oas/security-defined --- # security-defined @@ -90,7 +90,7 @@ components: ## Related rules -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) - [no-unused-components](./no-unused-components.md) ## Resources diff --git a/docs/rules/spec-components-invalid-map-name.md b/docs/rules/oas/spec-components-invalid-map-name.md similarity index 94% rename from docs/rules/spec-components-invalid-map-name.md rename to docs/rules/oas/spec-components-invalid-map-name.md index 355548271d..dc3a0b2f04 100644 --- a/docs/rules/spec-components-invalid-map-name.md +++ b/docs/rules/oas/spec-components-invalid-map-name.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/spec-components-invalid-map-name +slug: /docs/cli/rules/oas/spec-components-invalid-map-name --- # spec-components-invalid-map-name @@ -89,8 +89,8 @@ components: ## Related rules -- [configurable rules](./configurable-rules.md) -- [spec](./spec.md) +- [configurable rules](../configurable-rules.md) +- [spec](../spec.md) ## Resources diff --git a/docs/rules/spec-strict-refs.md b/docs/rules/oas/spec-strict-refs.md similarity index 92% rename from docs/rules/spec-strict-refs.md rename to docs/rules/oas/spec-strict-refs.md index 2fc28288ce..bb9c341005 100644 --- a/docs/rules/spec-strict-refs.md +++ b/docs/rules/oas/spec-strict-refs.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/spec-strict-refs +slug: /docs/cli/rules/oas/spec-strict-refs --- # spec-strict-refs @@ -36,7 +36,7 @@ The following is a list of elements the `$ref` can be used with according to the ## Configuration To configure the rule, add it to the `rules` object in your configuration file, and -set the desired [severity](../rules.md#severity-settings). +set the desired [severity](../../rules.md#severity-settings). | Option | Type | Description | | -------- | ------ | ---------------------------------------------------------------------------------------- | @@ -88,8 +88,8 @@ responses: ## Related rules -- [configurable rules](./configurable-rules.md) -- [spec](./spec.md) +- [configurable rules](../configurable-rules.md) +- [spec](../spec.md) ## Resources diff --git a/docs/rules/tag-description.md b/docs/rules/oas/tag-description.md similarity index 93% rename from docs/rules/tag-description.md rename to docs/rules/oas/tag-description.md index 33586d774e..7b6fc7b7f9 100644 --- a/docs/rules/tag-description.md +++ b/docs/rules/oas/tag-description.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/tag-description +slug: /docs/cli/rules/oas/tag-description --- # tag-description @@ -41,7 +41,7 @@ Remember folks, we use docs-as-code to write the docs, but the docs are the prod ## Configuration To configure the rule, add it to the `rules` object in your configuration file. -Set the desired [severity](../rules.md#severity-settings) for the rule. +Set the desired [severity](../../rules.md#severity-settings) for the rule. ```yaml rules: @@ -90,7 +90,7 @@ tags: - [tags-alphabetical](./tags-alphabetical.md) - [operation-description](./operation-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/tags-alphabetical.md b/docs/rules/oas/tags-alphabetical.md similarity index 96% rename from docs/rules/tags-alphabetical.md rename to docs/rules/oas/tags-alphabetical.md index 2edfe261e9..9874c47315 100644 --- a/docs/rules/tags-alphabetical.md +++ b/docs/rules/oas/tags-alphabetical.md @@ -1,5 +1,5 @@ --- -slug: /docs/cli/rules/tags-alphabetical +slug: /docs/cli/rules/oas/tags-alphabetical --- # tags-alphabetical @@ -77,7 +77,7 @@ tags: - [tag-description](./tag-description.md) - [operation-description](./operation-description.md) -- [configurable rules](./configurable-rules.md) +- [configurable rules](../configurable-rules.md) ## Resources diff --git a/docs/rules/recommended.md b/docs/rules/recommended.md index 8869d0ecb9..b45eb231a7 100644 --- a/docs/rules/recommended.md +++ b/docs/rules/recommended.md @@ -8,39 +8,39 @@ These are the rules in the `recommended` set, grouped by their severity. Errors: -- [no-empty-servers](./no-empty-servers.md) -- [no-enum-type-mismatch](./no-enum-type-mismatch.md) -- [no-example-value-and-externalValue](./no-example-value-and-externalValue.md) -- [no-identical-paths](./no-identical-paths.md) -- [no-path-trailing-slash](./no-path-trailing-slash.md) -- [no-server-trailing-slash](./no-server-trailing-slash.md) -- [no-server-variables-empty-enum](./no-server-variables-empty-enum.md) -- [no-undefined-server-variable](./no-undefined-server-variable.md) -- [no-unresolved-refs](./no-unresolved-refs.md) -- [operation-operationId-unique](./operation-operationId-unique.md) -- [operation-operationId-url-safe](./operation-operationId-url-safe.md) -- [operation-parameters-unique](./operation-parameters-unique.md) -- [operation-summary](./operation-summary.md) -- [path-declaration-must-exist](./path-declaration-must-exist.md) -- [path-not-include-query](./path-not-include-query.md) -- [path-parameters-defined](./path-parameters-defined.md) -- [security-defined](./security-defined.md) -- [spec-components-invalid-map-name](./spec-components-invalid-map-name.md) +- [no-empty-servers](./oas/no-empty-servers.md) +- [no-enum-type-mismatch](./oas/no-enum-type-mismatch.md) +- [no-example-value-and-externalValue](./oas/no-example-value-and-externalValue.md) +- [no-identical-paths](./oas/no-identical-paths.md) +- [no-path-trailing-slash](./oas/no-path-trailing-slash.md) +- [no-server-trailing-slash](./oas/no-server-trailing-slash.md) +- [no-server-variables-empty-enum](./oas/no-server-variables-empty-enum.md) +- [no-undefined-server-variable](./oas/no-undefined-server-variable.md) +- [no-unresolved-refs](./oas/no-unresolved-refs.md) +- [operation-operationId-unique](./oas/operation-operationId-unique.md) +- [operation-operationId-url-safe](./oas/operation-operationId-url-safe.md) +- [operation-parameters-unique](./oas/operation-parameters-unique.md) +- [operation-summary](./oas/operation-summary.md) +- [path-declaration-must-exist](./oas/path-declaration-must-exist.md) +- [path-not-include-query](./oas/path-not-include-query.md) +- [path-parameters-defined](./oas/path-parameters-defined.md) +- [security-defined](./oas/security-defined.md) +- [spec-components-invalid-map-name](./oas/spec-components-invalid-map-name.md) - [spec](./spec.md) Warnings: - [configurable rules](./configurable-rules.md) -- [info-license-url](./info-license-url.md) -- [info-license](./info-license.md) -- [no-ambiguous-paths](./no-ambiguous-paths.md) -- [no-invalid-media-type-examples](./no-invalid-media-type-examples.md) -- [no-server-example.com](./no-server-example-com.md) -- [no-unused-components](./no-unused-components.md) -- [operation-2xx-response](./operation-2xx-response.md) -- [operation-4xx-response](./operation-4xx-response.md) -- [operation-operationId](./operation-operationId.md) -- [tag-description](./tag-description.md) +- [info-license-url](./oas/info-license-url.md) +- [info-license](./oas/info-license.md) +- [no-ambiguous-paths](./oas/no-ambiguous-paths.md) +- [no-invalid-media-type-examples](./oas/no-invalid-media-type-examples.md) +- [no-server-example.com](./oas/no-server-example-com.md) +- [no-unused-components](./oas/no-unused-components.md) +- [operation-2xx-response](./oas/operation-2xx-response.md) +- [operation-4xx-response](./oas/operation-4xx-response.md) +- [operation-operationId](./oas/operation-operationId.md) +- [tag-description](./oas/tag-description.md) ## Recommended strict ruleset diff --git a/docs/sidebars.yaml b/docs/sidebars.yaml index 6fd99ac479..1e27d7c71f 100644 --- a/docs/sidebars.yaml +++ b/docs/sidebars.yaml @@ -75,58 +75,58 @@ - group: Built-in rules page: rules/built-in-rules.md items: - - page: rules/boolean-parameter-prefixes.md - - page: rules/component-name-unique.md - - page: rules/info-contact.md - - page: rules/info-license.md - - page: rules/info-license-url.md - - page: rules/no-ambiguous-paths.md - - page: rules/no-empty-servers.md - - page: rules/no-enum-type-mismatch.md - - page: rules/no-example-value-and-externalValue.md - - page: rules/no-http-verbs-in-paths.md - - page: rules/no-identical-paths.md - - page: rules/no-invalid-media-type-examples.md - - page: rules/no-invalid-parameter-examples.md - - page: rules/no-invalid-schema-examples.md - - page: rules/no-path-trailing-slash.md - - page: rules/no-required-schema-properties-undefined.md - - page: rules/no-server-example-com.md - - page: rules/no-server-trailing-slash.md - - page: rules/no-server-variables-empty-enum.md - - page: rules/no-undefined-server-variable.md - - page: rules/no-unresolved-refs.md - - page: rules/no-unused-components.md - - page: rules/operation-2xx-response.md - - page: rules/operation-4xx-problem-details-rfc7807.md - - page: rules/operation-4xx-response.md - - page: rules/operation-description.md - - page: rules/operation-operationId.md - - page: rules/operation-operationId-unique.md - - page: rules/operation-operationId-url-safe.md - - page: rules/operation-parameters-unique.md - - page: rules/operation-singular-tag.md - - page: rules/operation-summary.md - - page: rules/operation-tag-defined.md - - page: rules/parameter-description.md - - page: rules/path-declaration-must-exist.md - - page: rules/path-excludes-patterns.md - - page: rules/path-not-include-query.md - - page: rules/path-parameters-defined.md - - page: rules/path-segment-plural.md - - page: rules/paths-kebab-case.md - - page: rules/request-mime-type.md - - page: rules/required-string-property-missing-min-length.md - - page: rules/response-contains-header.md - - page: rules/response-contains-property.md - - page: rules/response-mime-type.md - - page: rules/scalar-property-missing-example.md - - page: rules/security-defined.md - - page: rules/spec-components-invalid-map-name.md + - page: rules/oas/boolean-parameter-prefixes.md + - page: rules/oas/component-name-unique.md + - page: rules/oas/info-contact.md + - page: rules/oas/info-license.md + - page: rules/oas/info-license-url.md + - page: rules/oas/no-ambiguous-paths.md + - page: rules/oas/no-empty-servers.md + - page: rules/oas/no-enum-type-mismatch.md + - page: rules/oas/no-example-value-and-externalValue.md + - page: rules/oas/no-http-verbs-in-paths.md + - page: rules/oas/no-identical-paths.md + - page: rules/oas/no-invalid-media-type-examples.md + - page: rules/oas/no-invalid-parameter-examples.md + - page: rules/oas/no-invalid-schema-examples.md + - page: rules/oas/no-path-trailing-slash.md + - page: rules/oas/no-required-schema-properties-undefined.md + - page: rules/oas/no-server-example-com.md + - page: rules/oas/no-server-trailing-slash.md + - page: rules/oas/no-server-variables-empty-enum.md + - page: rules/oas/no-undefined-server-variable.md + - page: rules/oas/no-unresolved-refs.md + - page: rules/oas/no-unused-components.md + - page: rules/oas/operation-2xx-response.md + - page: rules/oas/operation-4xx-problem-details-rfc7807.md + - page: rules/oas/operation-4xx-response.md + - page: rules/oas/operation-description.md + - page: rules/oas/operation-operationId.md + - page: rules/oas/operation-operationId-unique.md + - page: rules/oas/operation-operationId-url-safe.md + - page: rules/oas/operation-parameters-unique.md + - page: rules/oas/operation-singular-tag.md + - page: rules/oas/operation-summary.md + - page: rules/oas/operation-tag-defined.md + - page: rules/oas/parameter-description.md + - page: rules/oas/path-declaration-must-exist.md + - page: rules/oas/path-excludes-patterns.md + - page: rules/oas/path-not-include-query.md + - page: rules/oas/path-parameters-defined.md + - page: rules/oas/path-segment-plural.md + - page: rules/oas/paths-kebab-case.md + - page: rules/oas/required-string-property-missing-min-length.md + - page: rules/oas/response-contains-header.md + - page: rules/oas/response-contains-property.md + - page: rules/oas/response-mime-type.md + - page: rules/oas/request-mime-type.md + - page: rules/oas/scalar-property-missing-example.md + - page: rules/oas/security-defined.md + - page: rules/oas/spec-components-invalid-map-name.md - page: rules/spec.md - - page: rules/spec-strict-refs.md - - page: rules/tag-description.md - - page: rules/tags-alphabetical.md + - page: rules/oas/spec-strict-refs.md + - page: rules/oas/tag-description.md + - page: rules/oas/tags-alphabetical.md - page: rules/configurable-rules.md - group: Decorators page: decorators.md diff --git a/packages/cli/src/__tests__/utils.test.ts b/packages/cli/src/__tests__/utils.test.ts index 3223fa0928..9e28da152a 100644 --- a/packages/cli/src/__tests__/utils.test.ts +++ b/packages/cli/src/__tests__/utils.test.ts @@ -500,7 +500,7 @@ describe('checkIfRulesetExist', () => { oas3_1: {}, async2: {}, async3: {}, - arazzo: {}, + arazzo1: {}, }; expect(() => checkIfRulesetExist(rules)).toThrowError( '⚠️ No rules were configured. Learn how to configure rules: https://redocly.com/docs/cli/rules/' diff --git a/packages/cli/src/utils/miscellaneous.ts b/packages/cli/src/utils/miscellaneous.ts index 0acdbbe3c2..b474e6d7a8 100644 --- a/packages/cli/src/utils/miscellaneous.ts +++ b/packages/cli/src/utils/miscellaneous.ts @@ -529,7 +529,7 @@ export function checkIfRulesetExist(rules: typeof StyleguideConfig.prototype.rul ...rules.oas3_1, ...rules.async2, ...rules.async3, - ...rules.arazzo, + ...rules.arazzo1, }; if (isEmptyObject(ruleset)) { diff --git a/packages/core/__tests__/utils.ts b/packages/core/__tests__/utils.ts index 1e25e091f0..8cf3570efd 100644 --- a/packages/core/__tests__/utils.ts +++ b/packages/core/__tests__/utils.ts @@ -73,12 +73,10 @@ export async function makeConfig({ rules, decorators, configPath, - arazzoRules, }: { rules: Record; decorators?: Record; configPath?: string; - arazzoRules?: Record; }) { return new StyleguideConfig( await resolveStyleguideConfig({ @@ -86,7 +84,6 @@ export async function makeConfig({ plugins: [], extends: [], rules, - arazzoRules, decorators, }, }), diff --git a/packages/core/src/__tests__/lint.test.ts b/packages/core/src/__tests__/lint.test.ts index 3aa1ed00a0..58cba03144 100644 --- a/packages/core/src/__tests__/lint.test.ts +++ b/packages/core/src/__tests__/lint.test.ts @@ -295,7 +295,7 @@ describe('lint', () => { }, ], "message": "Expected type \`License\` (object) but got \`string\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -324,7 +324,7 @@ describe('lint', () => { }, ], "message": "Expected type \`License\` (object) but got \`string\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -1611,7 +1611,7 @@ describe('lint', () => { }, ], "message": "Property \`dependentRequired\` is not expected here.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, diff --git a/packages/core/src/bundle.ts b/packages/core/src/bundle.ts index cf7af97edd..d4c3b4baaa 100755 --- a/packages/core/src/bundle.ts +++ b/packages/core/src/bundle.ts @@ -303,7 +303,7 @@ export function mapTypeToComponent(typeName: string, version: SpecMajorVersion) default: return null; } - case SpecMajorVersion.Arazzo: + case SpecMajorVersion.Arazzo1: switch (typeName) { case 'Root.workflows_items.parameters_items': case 'Root.workflows_items.steps_items.parameters_items': @@ -408,7 +408,7 @@ function makeBundleVisitor( components = root.components = root.components || {}; } else if (version === SpecMajorVersion.Async3) { components = root.components = root.components || {}; - } else if (version === SpecMajorVersion.Arazzo) { + } else if (version === SpecMajorVersion.Arazzo1) { components = root.components = root.components || {}; } }, diff --git a/packages/core/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap b/packages/core/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap index 049cd5a681..f374c8234f 100644 --- a/packages/core/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +++ b/packages/core/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap @@ -2,9 +2,9 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1`] = ` { - "arazzoDecorators": {}, - "arazzoPreprocessors": {}, - "arazzoRules": { + "arazzo1Decorators": {}, + "arazzo1Preprocessors": {}, + "arazzo1Rules": { "criteria-unique": "warn", "no-actions-type-end": "warn", "no-criteria-xpath": "warn", @@ -13,7 +13,7 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "requestBody-replacements-unique": "warn", "sourceDescription-name-unique": "error", "sourceDescription-type": "error", - "spec": "error", + "sourceDescriptions-not-empty": "error", "step-onFailure-unique": "warn", "step-onSuccess-unique": "warn", "stepId-unique": "error", @@ -29,7 +29,6 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "info-license-strict": "warn", "no-channel-trailing-slash": "off", "operation-operationId": "warn", - "spec": "error", "tag-description": "warn", "tags-alphabetical": "off", }, @@ -41,7 +40,6 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "info-license-strict": "warn", "no-channel-trailing-slash": "off", "operation-operationId": "warn", - "spec": "error", "tag-description": "warn", "tags-alphabetical": "off", }, @@ -51,9 +49,48 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "oas2Preprocessors": {}, "oas2Rules": { "boolean-parameter-prefixes": "error", + "info-contact": "off", + "info-license": "warn", + "info-license-strict": "warn", + "info-license-url": "off", + "no-ambiguous-paths": "warn", + "no-enum-type-mismatch": "error", + "no-http-verbs-in-paths": "off", + "no-identical-paths": "error", + "no-invalid-parameter-examples": "off", + "no-invalid-schema-examples": "off", + "no-path-trailing-slash": "error", + "no-required-schema-properties-undefined": "off", + "no-unresolved-refs": "error", + "operation-2xx-response": "warn", + "operation-4xx-response": "error", + "operation-description": "error", + "operation-operationId": "warn", + "operation-operationId-unique": "error", + "operation-operationId-url-safe": "error", + "operation-parameters-unique": "error", + "operation-singular-tag": "off", + "operation-summary": "error", + "operation-tag-defined": "off", + "parameter-description": "off", + "path-declaration-must-exist": "error", + "path-excludes-patterns": "off", + "path-http-verbs-order": "error", + "path-not-include-query": "error", + "path-parameters-defined": "error", + "path-params-defined": "off", + "path-segment-plural": "off", + "paths-kebab-case": "off", "request-mime-type": "off", + "required-string-property-missing-min-length": "off", + "response-contains-header": "off", "response-contains-property": "off", "response-mime-type": "off", + "scalar-property-missing-example": "off", + "security-defined": "error", + "spec-strict-refs": "off", + "tag-description": "warn", + "tags-alphabetical": "off", }, "oas3_0Decorators": {}, "oas3_0Preprocessors": {}, @@ -61,22 +98,61 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "array-parameter-serialization": "off", "boolean-parameter-prefixes": "error", "component-name-unique": "off", + "info-contact": "off", + "info-license": "warn", + "info-license-strict": "warn", + "info-license-url": "off", + "no-ambiguous-paths": "warn", "no-empty-servers": "error", + "no-enum-type-mismatch": "error", "no-example-value-and-externalValue": "error", + "no-http-verbs-in-paths": "off", + "no-identical-paths": "error", "no-invalid-media-type-examples": { "allowAdditionalProperties": false, "severity": "error", }, + "no-invalid-parameter-examples": "off", + "no-invalid-schema-examples": "off", + "no-path-trailing-slash": "error", + "no-required-schema-properties-undefined": "off", "no-server-example.com": "warn", "no-server-trailing-slash": "error", "no-server-variables-empty-enum": "error", "no-undefined-server-variable": "error", + "no-unresolved-refs": "error", "no-unused-components": "warn", + "operation-2xx-response": "warn", "operation-4xx-problem-details-rfc7807": "off", + "operation-4xx-response": "error", + "operation-description": "error", + "operation-operationId": "warn", + "operation-operationId-unique": "error", + "operation-operationId-url-safe": "error", + "operation-parameters-unique": "error", + "operation-singular-tag": "off", + "operation-summary": "error", + "operation-tag-defined": "off", + "parameter-description": "off", + "path-declaration-must-exist": "error", + "path-excludes-patterns": "off", + "path-http-verbs-order": "error", + "path-not-include-query": "error", + "path-parameters-defined": "error", + "path-params-defined": "off", + "path-segment-plural": "off", + "paths-kebab-case": "off", "request-mime-type": "off", + "required-string-property-missing-min-length": "off", + "response-contains-header": "off", "response-contains-property": "off", "response-mime-type": "off", + "scalar-property-missing-example": "off", + "security-defined": "error", "spec-components-invalid-map-name": "error", + "spec-strict-refs": "off", + "tag-description": "warn", + "tags-alphabetical": "off", }, "oas3_1Decorators": {}, "oas3_1Preprocessors": {}, @@ -84,31 +160,14 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "array-parameter-serialization": "off", "boolean-parameter-prefixes": "error", "component-name-unique": "off", - "no-empty-servers": "error", - "no-example-value-and-externalValue": "error", - "no-invalid-media-type-examples": "error", - "no-server-example.com": "warn", - "no-server-trailing-slash": "error", - "no-server-variables-empty-enum": "error", - "no-undefined-server-variable": "error", - "no-unused-components": "warn", - "operation-4xx-problem-details-rfc7807": "off", - "request-mime-type": "off", - "response-contains-property": "off", - "response-mime-type": "off", - "spec-components-invalid-map-name": "error", - }, - "preprocessors": {}, - "recommendedFallback": false, - "rules": { - "boolean-parameter-prefixes": "error", "info-contact": "off", "info-license": "warn", "info-license-strict": "warn", "info-license-url": "off", - "local/operation-id-not-test": "error", "no-ambiguous-paths": "warn", + "no-empty-servers": "error", "no-enum-type-mismatch": "error", + "no-example-value-and-externalValue": "error", "no-http-verbs-in-paths": "off", "no-identical-paths": "error", "no-invalid-media-type-examples": "error", @@ -116,8 +175,14 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "no-invalid-schema-examples": "off", "no-path-trailing-slash": "error", "no-required-schema-properties-undefined": "off", + "no-server-example.com": "warn", + "no-server-trailing-slash": "error", + "no-server-variables-empty-enum": "error", + "no-undefined-server-variable": "error", "no-unresolved-refs": "error", + "no-unused-components": "warn", "operation-2xx-response": "warn", + "operation-4xx-problem-details-rfc7807": "off", "operation-4xx-response": "error", "operation-description": "error", "operation-operationId": "warn", @@ -136,23 +201,38 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1 "path-params-defined": "off", "path-segment-plural": "off", "paths-kebab-case": "off", + "request-mime-type": "off", "required-string-property-missing-min-length": "off", "response-contains-header": "off", + "response-contains-property": "off", + "response-mime-type": "off", "scalar-property-missing-example": "off", "security-defined": "error", - "spec": "error", + "spec-components-invalid-map-name": "error", "spec-strict-refs": "off", "tag-description": "warn", "tags-alphabetical": "off", }, + "preprocessors": {}, + "recommendedFallback": false, + "rules": { + "boolean-parameter-prefixes": "error", + "local/operation-id-not-test": "error", + "no-invalid-media-type-examples": "error", + "operation-2xx-response": "warn", + "operation-4xx-response": "error", + "operation-description": "error", + "path-http-verbs-order": "error", + "struct": "error", + }, } `; exports[`resolveStyleguideConfig should resolve extends with local file config which contains path to nested config 1`] = ` { - "arazzoDecorators": {}, - "arazzoPreprocessors": {}, - "arazzoRules": { + "arazzo1Decorators": {}, + "arazzo1Preprocessors": {}, + "arazzo1Rules": { "criteria-unique": "warn", "no-actions-type-end": "warn", "no-criteria-xpath": "warn", @@ -161,7 +241,7 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "requestBody-replacements-unique": "warn", "sourceDescription-name-unique": "error", "sourceDescription-type": "error", - "spec": "error", + "sourceDescriptions-not-empty": "error", "step-onFailure-unique": "warn", "step-onSuccess-unique": "warn", "stepId-unique": "error", @@ -177,7 +257,6 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "info-license-strict": "warn", "no-channel-trailing-slash": "off", "operation-operationId": "warn", - "spec": "error", "tag-description": "warn", "tags-alphabetical": "off", }, @@ -189,7 +268,6 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "info-license-strict": "warn", "no-channel-trailing-slash": "off", "operation-operationId": "warn", - "spec": "error", "tag-description": "warn", "tags-alphabetical": "off", }, @@ -199,9 +277,48 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "oas2Preprocessors": {}, "oas2Rules": { "boolean-parameter-prefixes": "error", + "info-contact": "off", + "info-license": "warn", + "info-license-strict": "warn", + "info-license-url": "off", + "no-ambiguous-paths": "warn", + "no-enum-type-mismatch": "error", + "no-http-verbs-in-paths": "off", + "no-identical-paths": "error", + "no-invalid-parameter-examples": "off", + "no-invalid-schema-examples": "off", + "no-path-trailing-slash": "error", + "no-required-schema-properties-undefined": "off", + "no-unresolved-refs": "error", + "operation-2xx-response": "error", + "operation-4xx-response": "off", + "operation-description": "off", + "operation-operationId": "warn", + "operation-operationId-unique": "error", + "operation-operationId-url-safe": "error", + "operation-parameters-unique": "error", + "operation-singular-tag": "off", + "operation-summary": "error", + "operation-tag-defined": "off", + "parameter-description": "off", + "path-declaration-must-exist": "error", + "path-excludes-patterns": "off", + "path-http-verbs-order": "off", + "path-not-include-query": "error", + "path-parameters-defined": "error", + "path-params-defined": "off", + "path-segment-plural": "off", + "paths-kebab-case": "off", "request-mime-type": "off", + "required-string-property-missing-min-length": "off", + "response-contains-header": "off", "response-contains-property": "off", "response-mime-type": "off", + "scalar-property-missing-example": "off", + "security-defined": "error", + "spec-strict-refs": "off", + "tag-description": "warn", + "tags-alphabetical": "off", }, "oas3_0Decorators": {}, "oas3_0Preprocessors": {}, @@ -209,22 +326,61 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "array-parameter-serialization": "off", "boolean-parameter-prefixes": "error", "component-name-unique": "off", + "info-contact": "off", + "info-license": "warn", + "info-license-strict": "warn", + "info-license-url": "off", + "no-ambiguous-paths": "warn", "no-empty-servers": "error", + "no-enum-type-mismatch": "error", "no-example-value-and-externalValue": "error", - "no-invalid-media-type-examples": { + "no-http-verbs-in-paths": "off", + "no-identical-paths": "error", + "no-invalid-media-type-examples": { "allowAdditionalProperties": false, "severity": "warn", }, + "no-invalid-parameter-examples": "off", + "no-invalid-schema-examples": "off", + "no-path-trailing-slash": "error", + "no-required-schema-properties-undefined": "off", "no-server-example.com": "warn", "no-server-trailing-slash": "error", "no-server-variables-empty-enum": "error", "no-undefined-server-variable": "error", + "no-unresolved-refs": "error", "no-unused-components": "warn", + "operation-2xx-response": "error", "operation-4xx-problem-details-rfc7807": "off", + "operation-4xx-response": "off", + "operation-description": "off", + "operation-operationId": "warn", + "operation-operationId-unique": "error", + "operation-operationId-url-safe": "error", + "operation-parameters-unique": "error", + "operation-singular-tag": "off", + "operation-summary": "error", + "operation-tag-defined": "off", + "parameter-description": "off", + "path-declaration-must-exist": "error", + "path-excludes-patterns": "off", + "path-http-verbs-order": "off", + "path-not-include-query": "error", + "path-parameters-defined": "error", + "path-params-defined": "off", + "path-segment-plural": "off", + "paths-kebab-case": "off", "request-mime-type": "off", + "required-string-property-missing-min-length": "off", + "response-contains-header": "off", "response-contains-property": "off", "response-mime-type": "off", + "scalar-property-missing-example": "off", + "security-defined": "error", "spec-components-invalid-map-name": "error", + "spec-strict-refs": "off", + "tag-description": "warn", + "tags-alphabetical": "off", }, "oas3_1Decorators": {}, "oas3_1Preprocessors": {}, @@ -232,49 +388,14 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "array-parameter-serialization": "off", "boolean-parameter-prefixes": "error", "component-name-unique": "off", - "no-empty-servers": "error", - "no-example-value-and-externalValue": "error", - "no-invalid-media-type-examples": "warn", - "no-server-example.com": "warn", - "no-server-trailing-slash": "error", - "no-server-variables-empty-enum": "error", - "no-undefined-server-variable": "error", - "no-unused-components": "warn", - "operation-4xx-problem-details-rfc7807": "off", - "request-mime-type": "off", - "response-contains-property": "off", - "response-mime-type": "off", - "spec-components-invalid-map-name": "error", - }, - "preprocessors": {}, - "recommendedFallback": undefined, - "rules": { - "assertions": [ - { - "assertionId": "rule/path-item-get-defined", - "defined": true, - "message": "Every path item must have a GET operation.", - "property": "get", - "subject": "PathItem", - }, - { - "assertionId": "rule/tag-description", - "message": "Tag description must be at least 13 characters and end with a full stop.", - "minLength": 13, - "pattern": "/\\.$/", - "property": "description", - "severity": "error", - "subject": "Tag", - }, - ], - "boolean-parameter-prefixes": "error", "info-contact": "off", "info-license": "warn", "info-license-strict": "warn", "info-license-url": "off", - "local/operation-id-not-test": "error", "no-ambiguous-paths": "warn", + "no-empty-servers": "error", "no-enum-type-mismatch": "error", + "no-example-value-and-externalValue": "error", "no-http-verbs-in-paths": "off", "no-identical-paths": "error", "no-invalid-media-type-examples": "warn", @@ -282,8 +403,14 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "no-invalid-schema-examples": "off", "no-path-trailing-slash": "error", "no-required-schema-properties-undefined": "off", + "no-server-example.com": "warn", + "no-server-trailing-slash": "error", + "no-server-variables-empty-enum": "error", + "no-undefined-server-variable": "error", "no-unresolved-refs": "error", + "no-unused-components": "warn", "operation-2xx-response": "error", + "operation-4xx-problem-details-rfc7807": "off", "operation-4xx-response": "off", "operation-description": "off", "operation-operationId": "warn", @@ -302,14 +429,45 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w "path-params-defined": "off", "path-segment-plural": "off", "paths-kebab-case": "off", + "request-mime-type": "off", "required-string-property-missing-min-length": "off", "response-contains-header": "off", + "response-contains-property": "off", + "response-mime-type": "off", "scalar-property-missing-example": "off", "security-defined": "error", - "spec": "error", + "spec-components-invalid-map-name": "error", "spec-strict-refs": "off", "tag-description": "warn", "tags-alphabetical": "off", }, + "preprocessors": {}, + "recommendedFallback": undefined, + "rules": { + "assertions": [ + { + "assertionId": "rule/path-item-get-defined", + "defined": true, + "message": "Every path item must have a GET operation.", + "property": "get", + "subject": "PathItem", + }, + { + "assertionId": "rule/tag-description", + "message": "Tag description must be at least 13 characters and end with a full stop.", + "minLength": 13, + "pattern": "/\\.$/", + "property": "description", + "severity": "error", + "subject": "Tag", + }, + ], + "boolean-parameter-prefixes": "error", + "local/operation-id-not-test": "error", + "no-invalid-media-type-examples": "warn", + "operation-2xx-response": "error", + "operation-4xx-response": "off", + "struct": "error", + }, } `; diff --git a/packages/core/src/config/__tests__/__snapshots__/config.test.ts.snap b/packages/core/src/config/__tests__/__snapshots__/config.test.ts.snap index c482654234..3eb648f561 100644 --- a/packages/core/src/config/__tests__/__snapshots__/config.test.ts.snap +++ b/packages/core/src/config/__tests__/__snapshots__/config.test.ts.snap @@ -6,7 +6,7 @@ StyleguideConfig { "_usedVersions": Set {}, "configFile": undefined, "decorators": { - "arazzo": {}, + "arazzo1": {}, "async2": { "oas2": {}, "oas3_0": {}, @@ -50,7 +50,7 @@ StyleguideConfig { "pluginPaths": [], "plugins": [], "preprocessors": { - "arazzo": {}, + "arazzo1": {}, "async2": { "oas2": {}, "oas3_0": {}, @@ -119,7 +119,20 @@ StyleguideConfig { }, "recommendedFallback": false, "rules": { - "arazzo": {}, + "arazzo1": { + "oas2": { + "no-empty-servers": "error", + "operation-summary": "error", + }, + "oas3_0": { + "no-empty-servers": "error", + "operation-summary": "error", + }, + "oas3_1": { + "no-empty-servers": "error", + "operation-summary": "error", + }, + }, "async2": { "oas2": { "no-empty-servers": "error", diff --git a/packages/core/src/config/__tests__/config-resolvers.test.ts b/packages/core/src/config/__tests__/config-resolvers.test.ts index 9a33df8324..456fb69ee4 100644 --- a/packages/core/src/config/__tests__/config-resolvers.test.ts +++ b/packages/core/src/config/__tests__/config-resolvers.test.ts @@ -389,11 +389,23 @@ describe('resolveStyleguideConfig', () => { describe('resolveApis', () => { it('should resolve apis styleguideConfig and merge minimal extends', async () => { + const baseStyleguideConfig: StyleguideRawConfig = { + oas3_1Rules: { + 'operation-2xx-response': 'error', + }, + }; + const mergedStyleguidePreset = resolveStyleguideConfig({ + styleguideConfig: { ...baseStyleguideConfig, extends: ['minimal'] }, + }); const rawConfig: RawConfig = { apis: { petstore: { root: 'some/path', - styleguide: {}, + styleguide: { + oas3_1Rules: { + 'operation-2xx-response': 'error', + }, + }, }, }, styleguide: { @@ -401,7 +413,7 @@ describe('resolveApis', () => { }, }; const apisResult = await resolveApis({ rawConfig }); - expect(apisResult['petstore'].styleguide).toEqual(await minimalStyleguidePreset); + expect(apisResult['petstore'].styleguide).toEqual(await mergedStyleguidePreset); }); it('should not merge recommended extends by default by every level', async () => { diff --git a/packages/core/src/config/__tests__/config.test.ts b/packages/core/src/config/__tests__/config.test.ts index 650787fd54..9d3193c4b3 100644 --- a/packages/core/src/config/__tests__/config.test.ts +++ b/packages/core/src/config/__tests__/config.test.ts @@ -117,7 +117,7 @@ describe('getMergedConfig', () => { "_usedVersions": Set {}, "configFile": "redocly.yaml", "decorators": { - "arazzo": {}, + "arazzo1": {}, "async2": {}, "async3": {}, "oas2": {}, @@ -130,7 +130,7 @@ describe('getMergedConfig', () => { "pluginPaths": [], "plugins": [], "preprocessors": { - "arazzo": {}, + "arazzo1": {}, "async2": {}, "async3": {}, "oas2": {}, @@ -146,7 +146,9 @@ describe('getMergedConfig', () => { }, "recommendedFallback": false, "rules": { - "arazzo": {}, + "arazzo1": { + "operation-summary": "warn", + }, "async2": { "operation-summary": "warn", }, @@ -230,7 +232,7 @@ describe('getMergedConfig', () => { "_usedVersions": Set {}, "configFile": "redocly.yaml", "decorators": { - "arazzo": {}, + "arazzo1": {}, "async2": {}, "async3": {}, "oas2": {}, @@ -243,7 +245,7 @@ describe('getMergedConfig', () => { "pluginPaths": [], "plugins": [], "preprocessors": { - "arazzo": {}, + "arazzo1": {}, "async2": {}, "async3": {}, "oas2": {}, @@ -261,7 +263,10 @@ describe('getMergedConfig', () => { }, "recommendedFallback": false, "rules": { - "arazzo": {}, + "arazzo1": { + "no-empty-servers": "error", + "operation-summary": "error", + }, "async2": { "no-empty-servers": "error", "operation-summary": "error", diff --git a/packages/core/src/config/all.ts b/packages/core/src/config/all.ts index a6dd21f804..a672dd8c52 100644 --- a/packages/core/src/config/all.ts +++ b/packages/core/src/config/all.ts @@ -2,52 +2,47 @@ import type { PluginStyleguideConfig } from './types'; const all: PluginStyleguideConfig<'built-in'> = { rules: { + struct: 'error', + }, + oas2Rules: { + 'boolean-parameter-prefixes': 'error', 'info-contact': 'error', 'info-license': 'error', 'info-license-url': 'error', 'info-license-strict': 'error', - 'tag-description': 'error', - 'tags-alphabetical': 'error', - 'parameter-description': 'error', + 'no-path-trailing-slash': 'error', 'no-identical-paths': 'error', 'no-ambiguous-paths': 'error', - 'no-path-trailing-slash': 'error', - 'path-segment-plural': 'error', - 'path-declaration-must-exist': 'error', - 'path-not-include-query': 'error', - 'path-parameters-defined': 'error', - 'operation-description': 'error', - 'operation-2xx-response': 'error', - 'operation-4xx-response': 'error', - 'operation-operationId': 'error', + 'no-invalid-schema-examples': 'error', + 'no-invalid-parameter-examples': 'error', + 'no-http-verbs-in-paths': 'error', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'error', 'operation-summary': 'error', + 'operation-operationId': 'error', 'operation-operationId-unique': 'error', 'operation-operationId-url-safe': 'error', + 'operation-description': 'error', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-parameters-unique': 'error', 'operation-tag-defined': 'error', - 'security-defined': 'error', 'operation-singular-tag': 'error', - 'no-unresolved-refs': 'error', - 'no-enum-type-mismatch': 'error', + 'parameter-description': 'error', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', 'paths-kebab-case': 'error', - 'no-http-verbs-in-paths': 'error', 'path-excludes-patterns': { severity: 'error', patterns: [], }, - spec: 'error', - 'no-invalid-schema-examples': 'error', - 'no-invalid-parameter-examples': 'error', - 'scalar-property-missing-example': 'error', - 'spec-strict-refs': 'error', 'path-http-verbs-order': 'error', 'path-params-defined': 'error', + 'path-segment-plural': 'error', 'required-string-property-missing-min-length': 'error', 'response-contains-header': 'error', - 'no-required-schema-properties-undefined': 'error', - }, - oas2Rules: { - 'boolean-parameter-prefixes': 'error', 'request-mime-type': { severity: 'error', allowedValues: ['application/json'], @@ -57,8 +52,29 @@ const all: PluginStyleguideConfig<'built-in'> = { allowedValues: ['application/json'], }, 'response-contains-property': 'error', + 'security-defined': 'error', + 'spec-strict-refs': 'error', + 'scalar-property-missing-example': 'error', + 'tag-description': 'error', + 'tags-alphabetical': 'error', }, oas3_0Rules: { + 'array-parameter-serialization': 'error', + 'boolean-parameter-prefixes': 'error', + 'component-name-unique': 'error', + 'info-contact': 'error', + 'info-license': 'error', + 'info-license-url': 'error', + 'info-license-strict': 'error', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'error', + 'no-invalid-schema-examples': 'error', + 'no-invalid-parameter-examples': 'error', + 'no-http-verbs-in-paths': 'error', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'error', 'no-invalid-media-type-examples': 'error', 'no-server-example.com': 'error', 'no-server-trailing-slash': 'error', @@ -67,8 +83,31 @@ const all: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'error', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', + 'operation-summary': 'error', + 'operation-operationId': 'error', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'error', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-4xx-problem-details-rfc7807': 'error', - 'boolean-parameter-prefixes': 'error', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'error', + 'operation-singular-tag': 'error', + 'parameter-description': 'error', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'error', + 'path-excludes-patterns': { + severity: 'error', + patterns: [], + }, + 'path-http-verbs-order': 'error', + 'path-params-defined': 'error', + 'path-segment-plural': 'error', + 'required-string-property-missing-min-length': 'error', + 'response-contains-header': 'error', 'request-mime-type': { severity: 'error', allowedValues: ['application/json'], @@ -77,12 +116,31 @@ const all: PluginStyleguideConfig<'built-in'> = { severity: 'error', allowedValues: ['application/json'], }, - 'component-name-unique': 'error', 'response-contains-property': 'error', + 'security-defined': 'error', + 'spec-strict-refs': 'error', + 'scalar-property-missing-example': 'error', 'spec-components-invalid-map-name': 'error', - 'array-parameter-serialization': 'error', + 'tag-description': 'error', + 'tags-alphabetical': 'error', }, oas3_1Rules: { + 'array-parameter-serialization': 'error', + 'boolean-parameter-prefixes': 'error', + 'component-name-unique': 'error', + 'info-contact': 'error', + 'info-license': 'error', + 'info-license-url': 'error', + 'info-license-strict': 'error', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'error', + 'no-invalid-schema-examples': 'error', + 'no-invalid-parameter-examples': 'error', + 'no-http-verbs-in-paths': 'error', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'error', 'no-invalid-media-type-examples': 'error', 'no-server-example.com': 'error', 'no-server-trailing-slash': 'error', @@ -91,8 +149,31 @@ const all: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'error', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', + 'parameter-description': 'error', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'error', + 'path-excludes-patterns': { + severity: 'error', + patterns: [], + }, + 'path-http-verbs-order': 'error', + 'path-params-defined': 'error', + 'path-segment-plural': 'error', + 'operation-summary': 'error', + 'operation-operationId': 'error', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'error', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-4xx-problem-details-rfc7807': 'error', - 'boolean-parameter-prefixes': 'error', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'error', + 'operation-singular-tag': 'error', + 'required-string-property-missing-min-length': 'error', + 'response-contains-header': 'error', 'request-mime-type': { severity: 'error', allowedValues: ['application/json'], @@ -101,47 +182,48 @@ const all: PluginStyleguideConfig<'built-in'> = { severity: 'error', allowedValues: ['application/json'], }, - 'component-name-unique': 'error', 'response-contains-property': 'error', + 'security-defined': 'error', + 'spec-strict-refs': 'error', + 'scalar-property-missing-example': 'error', 'spec-components-invalid-map-name': 'error', - 'array-parameter-serialization': 'error', + 'tag-description': 'error', + 'tags-alphabetical': 'error', }, async2Rules: { - spec: 'error', + 'channels-kebab-case': 'error', 'info-contact': 'error', 'info-license-strict': 'error', + 'no-channel-trailing-slash': 'error', 'operation-operationId': 'error', 'tag-description': 'error', 'tags-alphabetical': 'error', - 'channels-kebab-case': 'error', - 'no-channel-trailing-slash': 'error', }, async3Rules: { - spec: 'error', + 'channels-kebab-case': 'error', 'info-contact': 'error', 'info-license-strict': 'error', + 'no-channel-trailing-slash': 'error', 'operation-operationId': 'error', 'tag-description': 'error', 'tags-alphabetical': 'error', - 'channels-kebab-case': 'error', - 'no-channel-trailing-slash': 'error', }, - arazzoRules: { - spec: 'error', + arazzo1Rules: { + 'criteria-unique': 'error', + 'no-criteria-xpath': 'error', + 'no-actions-type-end': 'error', 'parameters-not-in-body': 'error', + 'parameters-unique': 'error', + 'requestBody-replacements-unique': 'error', 'sourceDescription-type': 'error', - 'version-enum': 'error', - 'workflowId-unique': 'error', + 'step-onSuccess-unique': 'error', + 'step-onFailure-unique': 'error', 'stepId-unique': 'error', 'sourceDescription-name-unique': 'error', + 'sourceDescriptions-not-empty': 'error', + 'version-enum': 'error', + 'workflowId-unique': 'error', 'workflow-dependsOn': 'error', - 'parameters-unique': 'error', - 'step-onSuccess-unique': 'error', - 'step-onFailure-unique': 'error', - 'requestBody-replacements-unique': 'error', - 'no-criteria-xpath': 'error', - 'no-actions-type-end': 'error', - 'criteria-unique': 'error', }, }; diff --git a/packages/core/src/config/builtIn.ts b/packages/core/src/config/builtIn.ts index ad3975ce50..ccf197ae10 100644 --- a/packages/core/src/config/builtIn.ts +++ b/packages/core/src/config/builtIn.ts @@ -2,16 +2,17 @@ import recommended from './recommended'; import recommendedStrict from './recommended-strict'; import all from './all'; import minimal from './minimal'; +import specArazzo from './spec-arazzo'; import { rules as oas3Rules, preprocessors as oas3Preprocessors } from '../rules/oas3'; import { rules as oas2Rules, preprocessors as oas2Preprocessors } from '../rules/oas2'; import { rules as async2Rules, preprocessors as async2Preprocessors } from '../rules/async2'; import { rules as async3Rules, preprocessors as async3Preprocessors } from '../rules/async3'; -import { rules as arazzoRules, preprocessors as arazzoPreprocessors } from '../rules/arazzo'; +import { rules as arazzo1Rules, preprocessors as arazzoPreprocessors } from '../rules/arazzo'; import { decorators as oas3Decorators } from '../decorators/oas3'; import { decorators as oas2Decorators } from '../decorators/oas2'; import { decorators as async2Decorators } from '../decorators/async2'; import { decorators as async3Decorators } from '../decorators/async3'; -import { decorators as arazzoDecorators } from '../decorators/arazzo'; +import { decorators as arazzo1Decorators } from '../decorators/arazzo'; import type { CustomRulesConfig, StyleguideRawConfig, Plugin } from './types'; @@ -20,6 +21,7 @@ export const builtInConfigs: Record = { 'recommended-strict': recommendedStrict, minimal, all, + specArazzo, 'redocly-registry': { decorators: { 'registry-dependencies': 'on' }, }, @@ -32,7 +34,7 @@ export const defaultPlugin: Plugin = { oas2: oas2Rules, async2: async2Rules, async3: async3Rules, - arazzo: arazzoRules, + arazzo: arazzo1Rules, } as CustomRulesConfig, preprocessors: { oas3: oas3Preprocessors, @@ -46,7 +48,7 @@ export const defaultPlugin: Plugin = { oas2: oas2Decorators, async2: async2Decorators, async3: async3Decorators, - arazzo: arazzoDecorators, + arazzo: arazzo1Decorators, }, configs: builtInConfigs, }; diff --git a/packages/core/src/config/config-resolvers.ts b/packages/core/src/config/config-resolvers.ts index d585d54f3f..0aa3d19522 100644 --- a/packages/core/src/config/config-resolvers.ts +++ b/packages/core/src/config/config-resolvers.ts @@ -520,7 +520,7 @@ function getMergedRawStyleguideConfig( oas3_1Rules: { ...rootStyleguideConfig?.oas3_1Rules, ...apiStyleguideConfig?.oas3_1Rules }, async2Rules: { ...rootStyleguideConfig?.async2Rules, ...apiStyleguideConfig?.async2Rules }, async3Rules: { ...rootStyleguideConfig?.async3Rules, ...apiStyleguideConfig?.async3Rules }, - arazzoRules: { ...rootStyleguideConfig?.arazzoRules, ...apiStyleguideConfig?.arazzoRules }, + arazzo1Rules: { ...rootStyleguideConfig?.arazzo1Rules, ...apiStyleguideConfig?.arazzo1Rules }, preprocessors: { ...rootStyleguideConfig?.preprocessors, ...apiStyleguideConfig?.preprocessors, diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 365d57a4b3..90c3316bde 100755 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { parseYaml, stringifyYaml } from '../js-yaml'; -import { slash, doesYamlFileExist } from '../utils'; +import { slash, doesYamlFileExist, isPlainObject, showWarningForDeprecatedField } from '../utils'; import { SpecVersion, SpecMajorVersion } from '../oas-types'; import { isBrowser } from '../env'; import { getResolveConfig } from './utils'; @@ -67,16 +67,36 @@ export class StyleguideConfig { this.doNotResolveExamples = !!rawConfig.doNotResolveExamples; this.recommendedFallback = rawConfig.recommendedFallback || false; + const ruleGroups: (keyof ResolvedStyleguideConfig)[] = [ + 'rules', + 'oas2Rules', + 'oas3_0Rules', + 'oas3_1Rules', + 'async2Rules', + 'async3Rules', + 'arazzo1Rules', + ]; + + // To support backwards compatibility with the old `spec` key we rename it to `struct`. + for (const ruleGroup of ruleGroups) { + if ( + rawConfig[ruleGroup] && + isPlainObject(rawConfig[ruleGroup]) && + 'spec' in rawConfig[ruleGroup] + ) { + showWarningForDeprecatedField('spec', 'struct'); + rawConfig[ruleGroup].struct = rawConfig[ruleGroup].spec; + delete rawConfig[ruleGroup].spec; + } + } + this.rules = { [SpecVersion.OAS2]: { ...rawConfig.rules, ...rawConfig.oas2Rules }, [SpecVersion.OAS3_0]: { ...rawConfig.rules, ...rawConfig.oas3_0Rules }, [SpecVersion.OAS3_1]: { ...rawConfig.rules, ...rawConfig.oas3_1Rules }, [SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules }, [SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules }, - [SpecVersion.Arazzo]: { - ...(rawConfig.arazzoRules || {}), - ...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}), - }, + [SpecVersion.Arazzo1]: { ...rawConfig.rules, ...rawConfig.arazzo1Rules }, }; this.preprocessors = { @@ -85,7 +105,7 @@ export class StyleguideConfig { [SpecVersion.OAS3_1]: { ...rawConfig.preprocessors, ...rawConfig.oas3_1Preprocessors }, [SpecVersion.Async2]: { ...rawConfig.preprocessors, ...rawConfig.async2Preprocessors }, [SpecVersion.Async3]: { ...rawConfig.preprocessors, ...rawConfig.async3Preprocessors }, - [SpecVersion.Arazzo]: { ...rawConfig.arazzoPreprocessors }, + [SpecVersion.Arazzo1]: { ...rawConfig.arazzo1Preprocessors }, }; this.decorators = { @@ -94,7 +114,7 @@ export class StyleguideConfig { [SpecVersion.OAS3_1]: { ...rawConfig.decorators, ...rawConfig.oas3_1Decorators }, [SpecVersion.Async2]: { ...rawConfig.decorators, ...rawConfig.async2Decorators }, [SpecVersion.Async3]: { ...rawConfig.decorators, ...rawConfig.async3Decorators }, - [SpecVersion.Arazzo]: { ...rawConfig.arazzoDecorators }, + [SpecVersion.Arazzo1]: { ...rawConfig.arazzo1Decorators }, }; this.extendPaths = rawConfig.extendPaths || []; @@ -192,9 +212,9 @@ export class StyleguideConfig { if (!plugin.typeExtension.async3) continue; extendedTypes = plugin.typeExtension.async3(extendedTypes, version); break; - case SpecVersion.Arazzo: - if (!plugin.typeExtension.arazzo) continue; - extendedTypes = plugin.typeExtension.arazzo(extendedTypes, version); + case SpecVersion.Arazzo1: + if (!plugin.typeExtension.arazzo1) continue; + extendedTypes = plugin.typeExtension.arazzo1(extendedTypes, version); break; default: throw new Error('Not implemented'); @@ -306,15 +326,15 @@ export class StyleguideConfig { (p) => p.decorators?.async3 && asyncApi3Rules.push(p.decorators.async3) ); return asyncApi3Rules; - case SpecMajorVersion.Arazzo: + case SpecMajorVersion.Arazzo1: // eslint-disable-next-line no-case-declarations - const arazzoRules: ArazzoRuleSet[] = []; // default ruleset + const arazzo1Rules: ArazzoRuleSet[] = []; // default ruleset this.plugins.forEach( - (p) => p.preprocessors?.arazzo && arazzoRules.push(p.preprocessors.arazzo) + (p) => p.preprocessors?.arazzo && arazzo1Rules.push(p.preprocessors.arazzo) ); - this.plugins.forEach((p) => p.rules?.arazzo && arazzoRules.push(p.rules.arazzo)); - this.plugins.forEach((p) => p.decorators?.arazzo && arazzoRules.push(p.decorators.arazzo)); - return arazzoRules; + this.plugins.forEach((p) => p.rules?.arazzo && arazzo1Rules.push(p.rules.arazzo)); + this.plugins.forEach((p) => p.decorators?.arazzo && arazzo1Rules.push(p.decorators.arazzo)); + return arazzo1Rules; } } diff --git a/packages/core/src/config/minimal.ts b/packages/core/src/config/minimal.ts index f1ae082ea6..4e8831f7ce 100644 --- a/packages/core/src/config/minimal.ts +++ b/packages/core/src/config/minimal.ts @@ -2,54 +2,70 @@ import type { PluginStyleguideConfig } from './types'; const minimal: PluginStyleguideConfig<'built-in'> = { rules: { + struct: 'error', + }, + oas2Rules: { + 'boolean-parameter-prefixes': 'off', 'info-contact': 'off', 'info-license': 'off', 'info-license-url': 'off', 'info-license-strict': 'off', - 'tag-description': 'warn', - 'tags-alphabetical': 'off', - 'parameter-description': 'off', 'no-path-trailing-slash': 'warn', 'no-identical-paths': 'warn', 'no-ambiguous-paths': 'warn', - 'path-declaration-must-exist': 'warn', - 'path-not-include-query': 'warn', - 'path-parameters-defined': 'warn', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'warn', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', + 'operation-summary': 'warn', + 'operation-operationId': 'warn', + 'operation-operationId-unique': 'warn', + 'operation-operationId-url-safe': 'warn', 'operation-description': 'off', 'operation-2xx-response': 'warn', 'operation-4xx-response': 'off', - 'operation-operationId': 'warn', - 'operation-summary': 'warn', - 'operation-operationId-unique': 'warn', 'operation-parameters-unique': 'warn', 'operation-tag-defined': 'off', - 'security-defined': 'warn', - 'operation-operationId-url-safe': 'warn', 'operation-singular-tag': 'off', - 'no-unresolved-refs': 'error', - 'no-enum-type-mismatch': 'warn', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'warn', + 'path-not-include-query': 'warn', + 'path-parameters-defined': 'warn', 'paths-kebab-case': 'off', - spec: 'error', - 'spec-strict-refs': 'off', - 'no-http-verbs-in-paths': 'off', - 'no-invalid-parameter-examples': 'off', - 'no-invalid-schema-examples': 'off', 'path-excludes-patterns': 'off', 'path-http-verbs-order': 'off', 'path-params-defined': 'off', + 'path-segment-plural': 'off', 'required-string-property-missing-min-length': 'off', 'response-contains-header': 'off', - 'path-segment-plural': 'off', - 'scalar-property-missing-example': 'off', - 'no-required-schema-properties-undefined': 'off', - }, - oas2Rules: { - 'boolean-parameter-prefixes': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', + 'security-defined': 'warn', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, oas3_0Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'off', + 'info-license-url': 'off', + 'info-license-strict': 'off', + 'no-ambiguous-paths': 'warn', + 'no-path-trailing-slash': 'warn', + 'no-identical-paths': 'warn', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'warn', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': { severity: 'warn', allowAdditionalProperties: false, @@ -61,16 +77,55 @@ const minimal: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'warn', 'no-undefined-server-variable': 'warn', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'warn', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'warn', + 'operation-operationId': 'warn', + 'operation-operationId-unique': 'warn', + 'operation-operationId-url-safe': 'warn', + 'operation-description': 'off', + 'operation-2xx-response': 'warn', + 'operation-4xx-response': 'off', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'warn', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'warn', + 'path-not-include-query': 'warn', + 'path-parameters-defined': 'warn', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'warn', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'warn', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, oas3_1Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'off', + 'info-license-url': 'off', + 'info-license-strict': 'off', + 'no-path-trailing-slash': 'warn', + 'no-identical-paths': 'warn', + 'no-ambiguous-paths': 'warn', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'warn', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': 'warn', 'no-server-example.com': 'warn', 'no-server-trailing-slash': 'error', @@ -79,51 +134,72 @@ const minimal: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'warn', 'no-undefined-server-variable': 'warn', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'warn', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'warn', + 'operation-operationId': 'warn', + 'operation-operationId-unique': 'warn', + 'operation-operationId-url-safe': 'warn', + 'operation-description': 'off', + 'operation-2xx-response': 'warn', + 'operation-4xx-response': 'off', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'warn', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'warn', + 'path-not-include-query': 'warn', + 'path-parameters-defined': 'warn', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'warn', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'warn', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, async2Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'off', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'warn', 'tag-description': 'warn', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, async3Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'off', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'warn', 'tag-description': 'warn', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, - arazzoRules: { - spec: 'error', + arazzo1Rules: { + 'criteria-unique': 'off', + 'no-criteria-xpath': 'off', + 'no-actions-type-end': 'off', 'parameters-not-in-body': 'off', + 'parameters-unique': 'off', + 'requestBody-replacements-unique': 'off', 'sourceDescription-type': 'off', - 'version-enum': 'warn', - 'workflowId-unique': 'error', + 'sourceDescriptions-not-empty': 'off', + 'step-onSuccess-unique': 'off', + 'step-onFailure-unique': 'off', 'stepId-unique': 'error', 'sourceDescription-name-unique': 'off', + 'version-enum': 'off', + 'workflowId-unique': 'error', 'workflow-dependsOn': 'off', - 'parameters-unique': 'off', - 'step-onSuccess-unique': 'off', - 'step-onFailure-unique': 'off', - 'requestBody-replacements-unique': 'off', - 'no-criteria-xpath': 'off', - 'no-actions-type-end': 'off', - 'criteria-unique': 'off', }, }; diff --git a/packages/core/src/config/recommended-strict.ts b/packages/core/src/config/recommended-strict.ts index 9cd52552fe..344226cd1a 100644 --- a/packages/core/src/config/recommended-strict.ts +++ b/packages/core/src/config/recommended-strict.ts @@ -2,54 +2,70 @@ import type { PluginStyleguideConfig } from './types'; const recommendedStrict: PluginStyleguideConfig<'built-in'> = { rules: { + struct: 'error', + }, + oas2Rules: { + 'boolean-parameter-prefixes': 'off', 'info-contact': 'off', 'info-license': 'error', 'info-license-url': 'off', 'info-license-strict': 'error', - 'tag-description': 'error', - 'tags-alphabetical': 'off', - 'parameter-description': 'off', 'no-path-trailing-slash': 'error', 'no-identical-paths': 'error', 'no-ambiguous-paths': 'error', - 'path-declaration-must-exist': 'error', - 'path-not-include-query': 'error', - 'path-parameters-defined': 'error', - 'operation-description': 'off', - 'operation-2xx-response': 'error', - 'operation-4xx-response': 'error', - 'operation-operationId': 'error', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'operation-summary': 'error', + 'operation-operationId': 'error', 'operation-operationId-unique': 'error', 'operation-operationId-url-safe': 'error', + 'operation-description': 'off', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-parameters-unique': 'error', 'operation-tag-defined': 'off', - 'security-defined': 'error', 'operation-singular-tag': 'off', - 'no-unresolved-refs': 'error', - 'no-enum-type-mismatch': 'error', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', 'paths-kebab-case': 'off', - spec: 'error', - 'spec-strict-refs': 'off', - 'no-http-verbs-in-paths': 'off', - 'no-invalid-parameter-examples': 'off', - 'no-invalid-schema-examples': 'off', 'path-excludes-patterns': 'off', 'path-http-verbs-order': 'off', 'path-params-defined': 'off', 'path-segment-plural': 'off', 'required-string-property-missing-min-length': 'off', 'response-contains-header': 'off', - 'scalar-property-missing-example': 'off', - 'no-required-schema-properties-undefined': 'off', - }, - oas2Rules: { - 'boolean-parameter-prefixes': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'tag-description': 'error', + 'tags-alphabetical': 'off', }, oas3_0Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'error', + 'info-license-url': 'off', + 'info-license-strict': 'error', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'error', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': { severity: 'error', allowAdditionalProperties: false, @@ -61,16 +77,55 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'error', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'error', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'error', + 'operation-operationId': 'error', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'off', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'error', + 'tag-description': 'error', + 'tags-alphabetical': 'off', }, oas3_1Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'error', + 'info-license-url': 'off', + 'info-license-strict': 'error', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'error', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': 'error', 'no-server-example.com': 'error', 'no-server-trailing-slash': 'error', @@ -79,51 +134,72 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'error', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'error', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'error', + 'operation-operationId': 'error', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'off', + 'operation-2xx-response': 'error', + 'operation-4xx-response': 'error', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'error', + 'tag-description': 'error', + 'tags-alphabetical': 'off', }, async2Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'error', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'error', 'tag-description': 'error', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, async3Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'error', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'error', 'tag-description': 'error', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, - arazzoRules: { - spec: 'error', + arazzo1Rules: { + 'criteria-unique': 'error', + 'no-criteria-xpath': 'error', + 'no-actions-type-end': 'error', 'parameters-not-in-body': 'error', + 'parameters-unique': 'error', + 'requestBody-replacements-unique': 'error', 'sourceDescription-type': 'error', - 'version-enum': 'error', - 'workflowId-unique': 'error', + 'step-onSuccess-unique': 'error', + 'step-onFailure-unique': 'error', 'stepId-unique': 'error', 'sourceDescription-name-unique': 'error', + 'sourceDescriptions-not-empty': 'error', + 'version-enum': 'error', + 'workflowId-unique': 'error', 'workflow-dependsOn': 'error', - 'parameters-unique': 'error', - 'step-onSuccess-unique': 'error', - 'step-onFailure-unique': 'error', - 'requestBody-replacements-unique': 'error', - 'no-criteria-xpath': 'error', - 'no-actions-type-end': 'error', - 'criteria-unique': 'error', }, }; diff --git a/packages/core/src/config/recommended.ts b/packages/core/src/config/recommended.ts index 3a155d80c6..3da554861b 100644 --- a/packages/core/src/config/recommended.ts +++ b/packages/core/src/config/recommended.ts @@ -2,54 +2,70 @@ import type { PluginStyleguideConfig } from './types'; const recommended: PluginStyleguideConfig<'built-in'> = { rules: { + struct: 'error', + }, + oas2Rules: { + 'boolean-parameter-prefixes': 'off', 'info-contact': 'off', 'info-license': 'warn', 'info-license-url': 'off', 'info-license-strict': 'warn', - 'tag-description': 'warn', - 'tags-alphabetical': 'off', - 'parameter-description': 'off', 'no-path-trailing-slash': 'error', 'no-identical-paths': 'error', 'no-ambiguous-paths': 'warn', - 'path-declaration-must-exist': 'error', - 'path-not-include-query': 'error', - 'path-parameters-defined': 'error', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', + 'operation-summary': 'error', 'operation-description': 'off', - 'operation-2xx-response': 'warn', - 'operation-4xx-response': 'warn', 'operation-operationId': 'warn', - 'operation-summary': 'error', 'operation-operationId-unique': 'error', 'operation-operationId-url-safe': 'error', + 'operation-2xx-response': 'warn', + 'operation-4xx-response': 'warn', 'operation-parameters-unique': 'error', 'operation-tag-defined': 'off', - 'security-defined': 'error', 'operation-singular-tag': 'off', - 'no-unresolved-refs': 'error', - 'no-enum-type-mismatch': 'error', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', 'paths-kebab-case': 'off', - spec: 'error', - 'spec-strict-refs': 'off', - 'no-http-verbs-in-paths': 'off', - 'no-invalid-parameter-examples': 'off', - 'no-invalid-schema-examples': 'off', 'path-excludes-patterns': 'off', 'path-http-verbs-order': 'off', 'path-params-defined': 'off', 'path-segment-plural': 'off', 'required-string-property-missing-min-length': 'off', 'response-contains-header': 'off', - 'scalar-property-missing-example': 'off', - 'no-required-schema-properties-undefined': 'off', - }, - oas2Rules: { - 'boolean-parameter-prefixes': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, oas3_0Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'warn', + 'info-license-url': 'off', + 'info-license-strict': 'warn', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'warn', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': { severity: 'warn', allowAdditionalProperties: false, @@ -61,16 +77,55 @@ const recommended: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'warn', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'error', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'error', + 'operation-operationId': 'warn', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'off', + 'operation-2xx-response': 'warn', + 'operation-4xx-response': 'warn', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'error', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, oas3_1Rules: { + 'array-parameter-serialization': 'off', + 'boolean-parameter-prefixes': 'off', + 'component-name-unique': 'off', + 'info-contact': 'off', + 'info-license': 'warn', + 'info-license-url': 'off', + 'info-license-strict': 'warn', + 'no-path-trailing-slash': 'error', + 'no-identical-paths': 'error', + 'no-ambiguous-paths': 'warn', + 'no-invalid-schema-examples': 'off', + 'no-invalid-parameter-examples': 'off', + 'no-http-verbs-in-paths': 'off', + 'no-enum-type-mismatch': 'error', + 'no-unresolved-refs': 'error', + 'no-required-schema-properties-undefined': 'off', 'no-invalid-media-type-examples': 'warn', 'no-server-example.com': 'warn', 'no-server-trailing-slash': 'error', @@ -79,51 +134,72 @@ const recommended: PluginStyleguideConfig<'built-in'> = { 'no-unused-components': 'warn', 'no-undefined-server-variable': 'error', 'no-server-variables-empty-enum': 'error', - 'spec-components-invalid-map-name': 'error', - 'boolean-parameter-prefixes': 'off', - 'component-name-unique': 'off', + 'operation-summary': 'error', + 'operation-operationId': 'warn', + 'operation-operationId-unique': 'error', + 'operation-operationId-url-safe': 'error', + 'operation-description': 'off', + 'operation-2xx-response': 'warn', + 'operation-4xx-response': 'warn', 'operation-4xx-problem-details-rfc7807': 'off', + 'operation-parameters-unique': 'error', + 'operation-tag-defined': 'off', + 'operation-singular-tag': 'off', + 'parameter-description': 'off', + 'path-declaration-must-exist': 'error', + 'path-not-include-query': 'error', + 'path-parameters-defined': 'error', + 'paths-kebab-case': 'off', + 'path-excludes-patterns': 'off', + 'path-http-verbs-order': 'off', + 'path-params-defined': 'off', + 'path-segment-plural': 'off', + 'required-string-property-missing-min-length': 'off', + 'response-contains-header': 'off', 'request-mime-type': 'off', 'response-contains-property': 'off', 'response-mime-type': 'off', - 'array-parameter-serialization': 'off', + 'security-defined': 'error', + 'spec-strict-refs': 'off', + 'scalar-property-missing-example': 'off', + 'spec-components-invalid-map-name': 'error', + 'tag-description': 'warn', + 'tags-alphabetical': 'off', }, async2Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'warn', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'warn', 'tag-description': 'warn', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, async3Rules: { - spec: 'error', + 'channels-kebab-case': 'off', 'info-contact': 'off', 'info-license-strict': 'warn', + 'no-channel-trailing-slash': 'off', 'operation-operationId': 'warn', 'tag-description': 'warn', 'tags-alphabetical': 'off', - 'channels-kebab-case': 'off', - 'no-channel-trailing-slash': 'off', }, - arazzoRules: { - spec: 'error', + arazzo1Rules: { + 'criteria-unique': 'warn', + 'no-criteria-xpath': 'warn', + 'no-actions-type-end': 'warn', 'parameters-not-in-body': 'warn', + 'parameters-unique': 'error', + 'requestBody-replacements-unique': 'warn', 'sourceDescription-type': 'error', - 'version-enum': 'warn', - 'workflowId-unique': 'error', + 'step-onSuccess-unique': 'warn', + 'step-onFailure-unique': 'warn', 'stepId-unique': 'error', 'sourceDescription-name-unique': 'error', + 'sourceDescriptions-not-empty': 'error', + 'version-enum': 'warn', + 'workflowId-unique': 'error', 'workflow-dependsOn': 'error', - 'parameters-unique': 'error', - 'step-onSuccess-unique': 'warn', - 'step-onFailure-unique': 'warn', - 'requestBody-replacements-unique': 'warn', - 'no-criteria-xpath': 'warn', - 'no-actions-type-end': 'warn', - 'criteria-unique': 'warn', }, }; diff --git a/packages/core/src/config/spec-arazzo.ts b/packages/core/src/config/spec-arazzo.ts new file mode 100644 index 0000000000..d1326c38fc --- /dev/null +++ b/packages/core/src/config/spec-arazzo.ts @@ -0,0 +1,23 @@ +import type { PluginStyleguideConfig } from './types'; + +const specArazzo: PluginStyleguideConfig<'built-in'> = { + arazzo1Rules: { + 'parameters-not-in-body': 'error', + 'sourceDescription-type': 'error', + 'version-enum': 'error', + 'workflowId-unique': 'error', + 'stepId-unique': 'error', + 'sourceDescription-name-unique': 'error', + 'sourceDescriptions-not-empty': 'error', + 'workflow-dependsOn': 'error', + 'parameters-unique': 'error', + 'step-onSuccess-unique': 'error', + 'step-onFailure-unique': 'error', + 'requestBody-replacements-unique': 'error', + 'no-criteria-xpath': 'error', + 'no-actions-type-end': 'error', + 'criteria-unique': 'error', + }, +}; + +export default specArazzo; diff --git a/packages/core/src/config/types.ts b/packages/core/src/config/types.ts index 9f15af653b..67beb8b2ba 100644 --- a/packages/core/src/config/types.ts +++ b/packages/core/src/config/types.ts @@ -16,8 +16,8 @@ import type { Async3DecoratorsSet, Async3RuleSet, ArazzoRuleSet, - ArazzoPreprocessorsSet, - ArazzoDecoratorsSet, + Arazzo1PreprocessorsSet, + Arazzo1DecoratorsSet, RuleMap, } from '../oas-types'; import type { NodeType } from '../types'; @@ -25,10 +25,11 @@ import type { SkipFunctionContext } from '../visitors'; import type { BuiltInAsync2RuleId, BuiltInAsync3RuleId, - BuiltInCommonOASRuleId, + BuiltInCommonRuleId, BuiltInOAS2RuleId, BuiltInOAS3RuleId, - BuiltInArazzoRuleId, + BuiltInArazzo1RuleId, + BuiltInCommonArazzoRuleId, } from '../types/redocly-yaml'; import type { JSONSchema } from 'json-schema-to-ts'; @@ -58,13 +59,15 @@ export type StyleguideRawConfig = { doNotResolveExamples?: boolean; recommendedFallback?: boolean; - rules?: RuleMap; + rules?: + | RuleMap + | RuleMap; oas2Rules?: RuleMap; oas3_0Rules?: RuleMap; oas3_1Rules?: RuleMap; async2Rules?: RuleMap; async3Rules?: RuleMap; - arazzoRules?: RuleMap; + arazzo1Rules?: RuleMap; preprocessors?: Record; oas2Preprocessors?: Record; @@ -72,7 +75,7 @@ export type StyleguideRawConfig = { oas3_1Preprocessors?: Record; async2Preprocessors?: Record; async3Preprocessors?: Record; - arazzoPreprocessors?: Record; + arazzo1Preprocessors?: Record; decorators?: Record; oas2Decorators?: Record; @@ -80,7 +83,7 @@ export type StyleguideRawConfig = { oas3_1Decorators?: Record; async2Decorators?: Record; async3Decorators?: Record; - arazzoDecorators?: Record; + arazzo1Decorators?: Record; }; export type ApiStyleguideRawConfig = Omit; @@ -98,7 +101,7 @@ export type PreprocessorsConfig = { oas2?: Oas2PreprocessorsSet; async2?: Async2PreprocessorsSet; async3?: Async3PreprocessorsSet; - arazzo?: ArazzoPreprocessorsSet; + arazzo?: Arazzo1PreprocessorsSet; }; export type DecoratorsConfig = { @@ -106,7 +109,7 @@ export type DecoratorsConfig = { oas2?: Oas2DecoratorsSet; async2?: Async2DecoratorsSet; async3?: Async3DecoratorsSet; - arazzo?: ArazzoDecoratorsSet; + arazzo?: Arazzo1DecoratorsSet; }; export type TypesExtensionFn = ( @@ -287,18 +290,18 @@ export type RulesFields = | 'oas3_1Rules' | 'async2Rules' | 'async3Rules' - | 'arazzoRules' + | 'arazzo1Rules' | 'preprocessors' | 'oas2Preprocessors' | 'oas3_0Preprocessors' | 'oas3_1Preprocessors' | 'async2Preprocessors' | 'async3Preprocessors' - | 'arazzoPreprocessors' + | 'arazzo1Preprocessors' | 'decorators' | 'oas2Decorators' | 'oas3_0Decorators' | 'oas3_1Decorators' | 'async2Decorators' | 'async3Decorators' - | 'arazzoDecorators'; + | 'arazzo1Decorators'; diff --git a/packages/core/src/config/utils.ts b/packages/core/src/config/utils.ts index 13a64833ac..8a74602493 100644 --- a/packages/core/src/config/utils.ts +++ b/packages/core/src/config/utils.ts @@ -61,7 +61,7 @@ function extractFlatConfig< oas3_1Rules, async2Rules, async3Rules, - arazzoRules, + arazzo1Rules, preprocessors, oas2Preprocessors, @@ -69,7 +69,7 @@ function extractFlatConfig< oas3_1Preprocessors, async2Preprocessors, async3Preprocessors, - arazzoPreprocessors, + arazzo1Preprocessors, decorators, oas2Decorators, @@ -77,7 +77,7 @@ function extractFlatConfig< oas3_1Decorators, async2Decorators, async3Decorators, - arazzoDecorators, + arazzo1Decorators, ...rawConfigRest }: T): { @@ -94,7 +94,7 @@ function extractFlatConfig< oas3_1Rules, async2Rules, async3Rules, - arazzoRules, + arazzo1Rules, preprocessors, oas2Preprocessors, @@ -102,7 +102,7 @@ function extractFlatConfig< oas3_1Preprocessors, async2Preprocessors, async3Preprocessors, - arazzoPreprocessors, + arazzo1Preprocessors, decorators, oas2Decorators, @@ -110,7 +110,7 @@ function extractFlatConfig< oas3_1Decorators, async2Decorators, async3Decorators, - arazzoDecorators, + arazzo1Decorators, doNotResolveExamples: rawConfigRest.resolve?.doNotResolveExamples, }; @@ -169,7 +169,7 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { oas3_1Rules: {}, async2Rules: {}, async3Rules: {}, - arazzoRules: {}, + arazzo1Rules: {}, preprocessors: {}, oas2Preprocessors: {}, @@ -177,7 +177,7 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { oas3_1Preprocessors: {}, async2Preprocessors: {}, async3Preprocessors: {}, - arazzoPreprocessors: {}, + arazzo1Preprocessors: {}, decorators: {}, oas2Decorators: {}, @@ -185,7 +185,7 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { oas3_1Decorators: {}, async2Decorators: {}, async3Decorators: {}, - arazzoDecorators: {}, + arazzo1Decorators: {}, plugins: [], pluginPaths: [], @@ -210,8 +210,8 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { assignOnlyExistingConfig(result.async2Rules, rulesConf.rules); assignConfig(result.async3Rules, rulesConf.async3Rules); assignOnlyExistingConfig(result.async3Rules, rulesConf.rules); - assignConfig(result.arazzoRules, rulesConf.arazzoRules); - assignOnlyExistingConfig(result.arazzoRules, rulesConf.rules); + assignConfig(result.arazzo1Rules, rulesConf.arazzo1Rules); + assignOnlyExistingConfig(result.arazzo1Rules, rulesConf.rules); assignConfig(result.preprocessors, rulesConf.preprocessors); assignConfig(result.oas2Preprocessors, rulesConf.oas2Preprocessors); @@ -224,8 +224,8 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { assignOnlyExistingConfig(result.async2Preprocessors, rulesConf.preprocessors); assignConfig(result.async3Preprocessors, rulesConf.async3Preprocessors); assignOnlyExistingConfig(result.async3Preprocessors, rulesConf.preprocessors); - assignConfig(result.arazzoPreprocessors, rulesConf.arazzoPreprocessors); - assignOnlyExistingConfig(result.arazzoPreprocessors, rulesConf.preprocessors); + assignConfig(result.arazzo1Preprocessors, rulesConf.arazzo1Preprocessors); + assignOnlyExistingConfig(result.arazzo1Preprocessors, rulesConf.preprocessors); assignConfig(result.decorators, rulesConf.decorators); assignConfig(result.oas2Decorators, rulesConf.oas2Decorators); @@ -238,8 +238,8 @@ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) { assignOnlyExistingConfig(result.async2Decorators, rulesConf.decorators); assignConfig(result.async3Decorators, rulesConf.async3Decorators); assignOnlyExistingConfig(result.async3Decorators, rulesConf.decorators); - assignConfig(result.arazzoDecorators, rulesConf.arazzoDecorators); - assignOnlyExistingConfig(result.arazzoDecorators, rulesConf.decorators); + assignConfig(result.arazzo1Decorators, rulesConf.arazzo1Decorators); + assignOnlyExistingConfig(result.arazzo1Decorators, rulesConf.decorators); result.plugins!.push(...(rulesConf.plugins || [])); result.pluginPaths!.push(...(rulesConf.pluginPaths || [])); @@ -291,7 +291,8 @@ export function checkForDeprecatedFields( deprecatedField: keyof (DeprecatedInRawConfig & RawConfig), updatedField: keyof FlatRawConfig | undefined, rawConfig: DeprecatedInRawConfig & RawConfig & FlatRawConfig, - updatedObject: keyof FlatRawConfig | undefined + updatedObject: keyof FlatRawConfig | undefined, + link?: string | undefined ): void { const isDeprecatedFieldInApis = rawConfig.apis && @@ -301,7 +302,7 @@ export function checkForDeprecatedFields( ); if (rawConfig[deprecatedField] && updatedField === null) { - showWarningForDeprecatedField(deprecatedField); + showWarningForDeprecatedField(deprecatedField, undefined, updatedObject, link); } if (rawConfig[deprecatedField] && updatedField && rawConfig[updatedField]) { @@ -313,7 +314,7 @@ export function checkForDeprecatedFields( } if (rawConfig[deprecatedField] || isDeprecatedFieldInApis) { - showWarningForDeprecatedField(deprecatedField, updatedField, updatedObject); + showWarningForDeprecatedField(deprecatedField, updatedField, updatedObject, link); } } @@ -323,17 +324,28 @@ export function transformConfig( const migratedFields: [ keyof (DeprecatedInRawConfig & RawConfig), keyof FlatRawConfig | undefined, - keyof ThemeConfig | undefined + keyof ThemeConfig | undefined, + string | undefined ][] = [ - ['apiDefinitions', 'apis', undefined], - ['referenceDocs', 'openapi', 'theme'], - ['lint', undefined, undefined], - ['styleguide', undefined, undefined], - ['features.openapi', 'openapi', 'theme'], + ['apiDefinitions', 'apis', undefined, undefined], + ['referenceDocs', 'openapi', 'theme', undefined], + [ + 'lint', + undefined, + undefined, + 'https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties', + ], + [ + 'styleguide', + undefined, + undefined, + 'https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties', + ], + ['features.openapi', 'openapi', 'theme', undefined], ]; - for (const [deprecatedField, updatedField, updatedObject] of migratedFields) { - checkForDeprecatedFields(deprecatedField, updatedField, rawConfig, updatedObject); + for (const [deprecatedField, updatedField, updatedObject, link] of migratedFields) { + checkForDeprecatedFields(deprecatedField, updatedField, rawConfig, updatedObject, link); } const { apis, apiDefinitions, referenceDocs, lint, ...rest } = rawConfig; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 16d645f168..d96598fca2 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -8,7 +8,7 @@ export { pause, } from './utils'; export { Oas3_1Types } from './types/oas3_1'; -export { ArazzoTypes } from './types/arazzo'; +export { Arazzo1Types } from './types/arazzo'; export { Oas3Types } from './types/oas3'; export { Oas2Types } from './types/oas2'; export { AsyncApi2Types } from './types/asyncapi2'; diff --git a/packages/core/src/lint.ts b/packages/core/src/lint.ts index d8fa0ec100..796728c18a 100755 --- a/packages/core/src/lint.ts +++ b/packages/core/src/lint.ts @@ -7,7 +7,7 @@ import { normalizeTypes } from './types'; import { releaseAjvInstance } from './rules/ajv'; import { SpecVersion, getMajorSpecVersion, detectSpec, getTypes } from './oas-types'; import { createConfigTypes } from './types/redocly-yaml'; -import { Spec } from './rules/common/spec'; +import { Struct } from './rules/common/struct'; import { NoUnresolvedRefs } from './rules/no-unresolved-refs'; import type { StyleguideConfig, Config } from './config'; @@ -159,7 +159,7 @@ export async function lintConfig(opts: { { severity: severity || 'error', ruleId: 'configuration spec', - visitor: Spec({ severity: 'error' }), + visitor: Struct({ severity: 'error' }), }, { severity: severity || 'error', diff --git a/packages/core/src/oas-types.ts b/packages/core/src/oas-types.ts index 5f67b76f8f..17161a913a 100644 --- a/packages/core/src/oas-types.ts +++ b/packages/core/src/oas-types.ts @@ -3,7 +3,7 @@ import { Oas3Types } from './types/oas3'; import { Oas3_1Types } from './types/oas3_1'; import { AsyncApi2Types } from './types/asyncapi2'; import { AsyncApi3Types } from './types/asyncapi3'; -import { ArazzoTypes } from './types/arazzo'; +import { Arazzo1Types } from './types/arazzo'; import { isPlainObject } from './utils'; import { VERSION_PATTERN } from './typings/arazzo'; @@ -11,9 +11,11 @@ import type { BuiltInAsync2RuleId, BuiltInAsync3RuleId, BuiltInCommonOASRuleId, - BuiltInArazzoRuleId, + BuiltInArazzo1RuleId, BuiltInOAS2RuleId, BuiltInOAS3RuleId, + BuiltInCommonArazzoRuleId, + BuiltInCommonAsyncRuleId, } from './types/redocly-yaml'; import type { Oas3Rule, @@ -24,8 +26,8 @@ import type { Async2Rule, Async3Preprocessor, Async3Rule, - ArazzoPreprocessor, - ArazzoRule, + Arazzo1Preprocessor, + Arazzo1Rule, } from './visitors'; export enum SpecVersion { @@ -34,7 +36,7 @@ export enum SpecVersion { OAS3_1 = 'oas3_1', Async2 = 'async2', Async3 = 'async3', - Arazzo = 'arazzo', + Arazzo1 = 'arazzo1', } export enum SpecMajorVersion { @@ -42,7 +44,7 @@ export enum SpecMajorVersion { OAS3 = 'oas3', Async2 = 'async2', Async3 = 'async3', - Arazzo = 'arazzo', + Arazzo1 = 'arazzo1', } const typesMap = { @@ -51,7 +53,7 @@ const typesMap = { [SpecVersion.OAS3_1]: Oas3_1Types, [SpecVersion.Async2]: AsyncApi2Types, [SpecVersion.Async3]: AsyncApi3Types, - [SpecVersion.Arazzo]: ArazzoTypes, + [SpecVersion.Arazzo1]: Arazzo1Types, }; export type RuleMap = Record< @@ -69,18 +71,18 @@ export type Oas2RuleSet = RuleMap< T >; export type Async2RuleSet = RuleMap< - BuiltInAsync2RuleId | 'assertions', + BuiltInCommonAsyncRuleId |BuiltInAsync2RuleId | 'assertions', Async2Rule, T >; export type Async3RuleSet = RuleMap< - BuiltInAsync3RuleId | 'assertions', + BuiltInCommonAsyncRuleId | BuiltInAsync3RuleId | 'assertions', Async3Rule, T >; export type ArazzoRuleSet = RuleMap< - BuiltInArazzoRuleId | 'assertions', - ArazzoRule, + BuiltInCommonArazzoRuleId | BuiltInArazzo1RuleId | 'assertions', + Arazzo1Rule, T >; @@ -88,13 +90,13 @@ export type Oas3PreprocessorsSet = Record; export type Oas2PreprocessorsSet = Record; export type Async2PreprocessorsSet = Record; export type Async3PreprocessorsSet = Record; -export type ArazzoPreprocessorsSet = Record; +export type Arazzo1PreprocessorsSet = Record; export type Oas3DecoratorsSet = Record; export type Oas2DecoratorsSet = Record; export type Async2DecoratorsSet = Record; export type Async3DecoratorsSet = Record; -export type ArazzoDecoratorsSet = Record; +export type Arazzo1DecoratorsSet = Record; export function detectSpec(root: unknown): SpecVersion { if (!isPlainObject(root)) { @@ -134,7 +136,7 @@ export function detectSpec(root: unknown): SpecVersion { } if (typeof root.arazzo === 'string' && VERSION_PATTERN.test(root.arazzo)) { - return SpecVersion.Arazzo; + return SpecVersion.Arazzo1; } throw new Error(`Unsupported specification`); @@ -147,8 +149,8 @@ export function getMajorSpecVersion(version: SpecVersion): SpecMajorVersion { return SpecMajorVersion.Async2; } else if (version === SpecVersion.Async3) { return SpecMajorVersion.Async3; - } else if (version === SpecVersion.Arazzo) { - return SpecMajorVersion.Arazzo; + } else if (version === SpecVersion.Arazzo1) { + return SpecMajorVersion.Arazzo1; } else { return SpecMajorVersion.OAS3; } diff --git a/packages/core/src/rules/arazzo/__tests__/criteria-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/criteria-unique.test.ts index a1dd0753ba..0938e3a60c 100644 --- a/packages/core/src/rules/arazzo/__tests__/criteria-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/criteria-unique.test.ts @@ -84,8 +84,7 @@ describe('Arazzo criteria-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'criteria-unique': 'error' }, + rules: { 'criteria-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/no-actions-type-end.test.ts b/packages/core/src/rules/arazzo/__tests__/no-actions-type-end.test.ts index d262511992..79ce32beba 100644 --- a/packages/core/src/rules/arazzo/__tests__/no-actions-type-end.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/no-actions-type-end.test.ts @@ -71,8 +71,7 @@ describe('Arazzo no-actions-type-end', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'no-actions-type-end': 'error' }, + rules: { 'no-actions-type-end': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts b/packages/core/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts index 6d0e845cf6..f9e08dd777 100644 --- a/packages/core/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts @@ -76,8 +76,7 @@ describe('Arazzo no-criteria-xpath', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'no-criteria-xpath': 'error' }, + rules: { 'no-criteria-xpath': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/parameters-not-in-body.test.ts b/packages/core/src/rules/arazzo/__tests__/parameters-not-in-body.test.ts index ad552d7f61..177baf9a3c 100644 --- a/packages/core/src/rules/arazzo/__tests__/parameters-not-in-body.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/parameters-not-in-body.test.ts @@ -48,8 +48,7 @@ describe('Spot parameters-not-in-body', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'parameters-not-in-body': 'error' }, + rules: { 'parameters-not-in-body': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/parameters-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/parameters-unique.test.ts index 0d56c0eefc..f8b5062849 100644 --- a/packages/core/src/rules/arazzo/__tests__/parameters-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/parameters-unique.test.ts @@ -62,8 +62,7 @@ describe('Arazzo parameters-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'parameters-unique': 'error' }, + rules: { 'parameters-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/requestBody-replacements-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/requestBody-replacements-unique.test.ts index 261635f1a1..508310485a 100644 --- a/packages/core/src/rules/arazzo/__tests__/requestBody-replacements-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/requestBody-replacements-unique.test.ts @@ -71,8 +71,7 @@ describe('Arazzo requestBody-replacements-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'requestBody-replacements-unique': 'error' }, + rules: { 'requestBody-replacements-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts b/packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts index a0a9443cc3..79e6eedc27 100644 --- a/packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts @@ -41,8 +41,7 @@ describe('Arazzo sourceDescription-type', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'sourceDescription-type': 'error' }, + rules: { 'sourceDescription-type': 'error' }, }), }); @@ -70,8 +69,7 @@ describe('Arazzo sourceDescription-type', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'sourceDescription-type': 'off' }, + rules: { 'sourceDescription-type': 'off' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/sourceDescription-name-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/sourceDescription-name-unique.test.ts index 516fd19627..1fdf4f33fd 100644 --- a/packages/core/src/rules/arazzo/__tests__/sourceDescription-name-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/sourceDescription-name-unique.test.ts @@ -41,8 +41,7 @@ describe('Arazzo sourceDescription-name-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'sourceDescription-name-unique': 'error' }, + rules: { 'sourceDescription-name-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/sourceDescriptions-not-empty.test.ts b/packages/core/src/rules/arazzo/__tests__/sourceDescriptions-not-empty.test.ts new file mode 100644 index 0000000000..8be5ff7889 --- /dev/null +++ b/packages/core/src/rules/arazzo/__tests__/sourceDescriptions-not-empty.test.ts @@ -0,0 +1,104 @@ +import { outdent } from 'outdent'; +import { lintDocument } from '../../../lint'; +import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils'; +import { BaseResolver } from '../../../resolve'; + +describe('Arazzo sourceDescriptions-not-empty', () => { + const document1 = parseYamlToDocument( + outdent` + arazzo: '1.0.0' + info: + title: Cool API + version: 1.0.0 + description: A cool API + sourceDescriptions: + - name: museum-api + type: openapi + url: openapi.yaml + - name: museum-api + type: openapi + url: openapi.yaml + workflows: + - workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + parameters: + - in: header + name: Authorization + value: Basic Og== + steps: + - stepId: get-museum-hours + description: >- + Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description. + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + `, + 'arazzo.yaml' + ); + + const document2 = parseYamlToDocument( + outdent` + arazzo: '1.0.0' + info: + title: Cool API + version: 1.0.0 + description: A cool API + sourceDescriptions: [] + workflows: + - workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + parameters: + - in: header + name: Authorization + value: Basic Og== + steps: + - stepId: get-museum-hours + description: >- + Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description. + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + `, + 'arazzo.yaml' + ); + + it('should not report an error when sourceDescriptions have at least one entry.', async () => { + const results = await lintDocument({ + externalRefResolver: new BaseResolver(), + document: document1, + config: await makeConfig({ + rules: { 'sourceDescriptions-not-empty': 'error' }, + }), + }); + + expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); + }); + + it('should report an error when sourceDescriptions is empty list.', async () => { + const results = await lintDocument({ + externalRefResolver: new BaseResolver(), + document: document2, + config: await makeConfig({ + rules: { 'sourceDescriptions-not-empty': 'error' }, + }), + }); + + expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` + [ + { + "location": [ + { + "pointer": "#/sourceDescriptions", + "reportOnKey": false, + "source": "arazzo.yaml", + }, + ], + "message": "The \`sourceDescriptions\` list must have at least one entry.", + "ruleId": "sourceDescriptions-not-empty", + "severity": "error", + "suggest": [], + }, + ] + `); + }); +}); diff --git a/packages/core/src/rules/arazzo/__tests__/step-onFailure-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/step-onFailure-unique.test.ts index 424b9653ef..8e8e92cd55 100644 --- a/packages/core/src/rules/arazzo/__tests__/step-onFailure-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/step-onFailure-unique.test.ts @@ -60,8 +60,7 @@ describe('Arazzo step-onFailure-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'step-onFailure-unique': 'error' }, + rules: { 'step-onFailure-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/step-onSuccess-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/step-onSuccess-unique.test.ts index b109202b48..00aa6b9279 100644 --- a/packages/core/src/rules/arazzo/__tests__/step-onSuccess-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/step-onSuccess-unique.test.ts @@ -60,8 +60,7 @@ describe('Arazzo step-onSuccess-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'step-onSuccess-unique': 'error' }, + rules: { 'step-onSuccess-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/stepId-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/stepId-unique.test.ts index c187f47a19..153beb9773 100644 --- a/packages/core/src/rules/arazzo/__tests__/stepId-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/stepId-unique.test.ts @@ -57,8 +57,7 @@ describe('Arazzo stepId-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'stepId-unique': 'error' }, + rules: { 'stepId-unique': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/version-enum.test.ts b/packages/core/src/rules/arazzo/__tests__/version-enum.test.ts index 518e93ca88..d45562b48a 100644 --- a/packages/core/src/rules/arazzo/__tests__/version-enum.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/version-enum.test.ts @@ -38,8 +38,7 @@ describe('Arazzo version-enum', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'version-enum': 'error' }, + rules: { 'version-enum': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/workflow-dependsOn.test.ts b/packages/core/src/rules/arazzo/__tests__/workflow-dependsOn.test.ts index b706591f3a..cf740908a7 100644 --- a/packages/core/src/rules/arazzo/__tests__/workflow-dependsOn.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/workflow-dependsOn.test.ts @@ -131,8 +131,7 @@ describe('Arazzo workflow-dependsOn', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'workflow-dependsOn': 'error' }, + rules: { 'workflow-dependsOn': 'error' }, }), }); @@ -160,8 +159,7 @@ describe('Arazzo workflow-dependsOn', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'workflow-dependsOn': 'off' }, + rules: { 'workflow-dependsOn': 'off' }, }), }); @@ -173,8 +171,7 @@ describe('Arazzo workflow-dependsOn', () => { externalRefResolver: new BaseResolver(), document: documentWithNotExistingWorkflows, config: await makeConfig({ - rules: {}, - arazzoRules: { 'workflow-dependsOn': 'error' }, + rules: { 'workflow-dependsOn': 'error' }, }), }); diff --git a/packages/core/src/rules/arazzo/__tests__/workflowId-unique.test.ts b/packages/core/src/rules/arazzo/__tests__/workflowId-unique.test.ts index c8b6a1935a..e418d7b7a7 100644 --- a/packages/core/src/rules/arazzo/__tests__/workflowId-unique.test.ts +++ b/packages/core/src/rules/arazzo/__tests__/workflowId-unique.test.ts @@ -51,8 +51,7 @@ describe('Arazzo workflowId-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'workflowId-unique': 'error' }, + rules: { 'workflowId-unique': 'error' }, }), }); @@ -80,8 +79,7 @@ describe('Arazzo workflowId-unique', () => { externalRefResolver: new BaseResolver(), document, config: await makeConfig({ - rules: {}, - arazzoRules: { 'workflowId-unique': 'off' }, + rules: { 'workflowId-unique': 'off' }, }), }); diff --git a/packages/core/src/rules/arazzo/criteria-unique.ts b/packages/core/src/rules/arazzo/criteria-unique.ts index 82792296fa..8544de7da4 100644 --- a/packages/core/src/rules/arazzo/criteria-unique.ts +++ b/packages/core/src/rules/arazzo/criteria-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const CriteriaUnique: ArazzoRule = () => { +export const CriteriaUnique: Arazzo1Rule = () => { return { FailureActionObject: { enter(action, { report, location }: UserContext) { diff --git a/packages/core/src/rules/arazzo/index.ts b/packages/core/src/rules/arazzo/index.ts index c00261a2f3..9ab705dac6 100644 --- a/packages/core/src/rules/arazzo/index.ts +++ b/packages/core/src/rules/arazzo/index.ts @@ -1,7 +1,8 @@ -import { Spec } from '../common/spec'; +import { Struct } from '../common/struct'; import { Assertions } from '../common/assertions'; import { ParametersNotInBody } from '../spot/parameters-not-in-body'; -import { SourceDescriptionType } from '../arazzo/source-description-type'; +import { SourceDescriptionType } from '../arazzo/sourceDescription-type'; +import { SourceDescriptionsNotEmpty } from './sourceDescriptions-not-empty'; import { VersionEnum } from '../spot/version-enum'; import { WorkflowIdUnique } from './workflowId-unique'; import { StepIdUnique } from './stepId-unique'; @@ -15,26 +16,27 @@ import { NoCriteriaXpath } from '../spot/no-criteria-xpath'; import { NoActionsTypeEnd } from '../spot/no-actions-type-end'; import { CriteriaUnique } from './criteria-unique'; -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { ArazzoRuleSet } from '../../oas-types'; export const rules: ArazzoRuleSet<'built-in'> = { - spec: Spec as ArazzoRule, - assertions: Assertions as ArazzoRule, - 'parameters-not-in-body': ParametersNotInBody as ArazzoRule, - 'sourceDescription-type': SourceDescriptionType as ArazzoRule, - 'version-enum': VersionEnum as ArazzoRule, - 'workflowId-unique': WorkflowIdUnique as ArazzoRule, - 'stepId-unique': StepIdUnique as ArazzoRule, - 'sourceDescription-name-unique': SourceDescriptionsNameUnique as ArazzoRule, - 'workflow-dependsOn': WorkflowDependsOn as ArazzoRule, - 'parameters-unique': ParametersUnique as ArazzoRule, - 'step-onSuccess-unique': StepOnSuccessUnique as ArazzoRule, - 'step-onFailure-unique': StepOnFailureUnique as ArazzoRule, - 'requestBody-replacements-unique': RequestBodyReplacementsUnique as ArazzoRule, - 'no-criteria-xpath': NoCriteriaXpath as ArazzoRule, - 'no-actions-type-end': NoActionsTypeEnd as ArazzoRule, - 'criteria-unique': CriteriaUnique as ArazzoRule, + struct: Struct as Arazzo1Rule, + assertions: Assertions as Arazzo1Rule, + 'parameters-not-in-body': ParametersNotInBody as Arazzo1Rule, + 'sourceDescription-type': SourceDescriptionType as Arazzo1Rule, + 'version-enum': VersionEnum as Arazzo1Rule, + 'workflowId-unique': WorkflowIdUnique as Arazzo1Rule, + 'stepId-unique': StepIdUnique as Arazzo1Rule, + 'sourceDescription-name-unique': SourceDescriptionsNameUnique as Arazzo1Rule, + 'sourceDescriptions-not-empty': SourceDescriptionsNotEmpty as Arazzo1Rule, + 'workflow-dependsOn': WorkflowDependsOn as Arazzo1Rule, + 'parameters-unique': ParametersUnique as Arazzo1Rule, + 'step-onSuccess-unique': StepOnSuccessUnique as Arazzo1Rule, + 'step-onFailure-unique': StepOnFailureUnique as Arazzo1Rule, + 'requestBody-replacements-unique': RequestBodyReplacementsUnique as Arazzo1Rule, + 'no-criteria-xpath': NoCriteriaXpath as Arazzo1Rule, + 'no-actions-type-end': NoActionsTypeEnd as Arazzo1Rule, + 'criteria-unique': CriteriaUnique as Arazzo1Rule, }; export const preprocessors = {}; diff --git a/packages/core/src/rules/arazzo/parameters-unique.ts b/packages/core/src/rules/arazzo/parameters-unique.ts index b21f6fdc1a..686b9a54b1 100644 --- a/packages/core/src/rules/arazzo/parameters-unique.ts +++ b/packages/core/src/rules/arazzo/parameters-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const ParametersUnique: ArazzoRule = () => { +export const ParametersUnique: Arazzo1Rule = () => { return { Parameters: { enter(parameters, { report, location }: UserContext) { diff --git a/packages/core/src/rules/arazzo/requestBody-replacements-unique.ts b/packages/core/src/rules/arazzo/requestBody-replacements-unique.ts index 18b7b1e136..1b6d0ecb94 100644 --- a/packages/core/src/rules/arazzo/requestBody-replacements-unique.ts +++ b/packages/core/src/rules/arazzo/requestBody-replacements-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const RequestBodyReplacementsUnique: ArazzoRule = () => { +export const RequestBodyReplacementsUnique: Arazzo1Rule = () => { const seenReplacements = new Set(); return { diff --git a/packages/core/src/rules/arazzo/source-description-type.ts b/packages/core/src/rules/arazzo/sourceDescription-type.ts similarity index 53% rename from packages/core/src/rules/arazzo/source-description-type.ts rename to packages/core/src/rules/arazzo/sourceDescription-type.ts index efc4331394..f98cee8ca4 100644 --- a/packages/core/src/rules/arazzo/source-description-type.ts +++ b/packages/core/src/rules/arazzo/sourceDescription-type.ts @@ -1,16 +1,17 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const SourceDescriptionType: ArazzoRule = () => { +export const SourceDescriptionType: Arazzo1Rule = () => { return { SourceDescriptions: { - enter(SourceDescriptions, { report, location }: UserContext) { - for (const sourceDescription of SourceDescriptions) { + enter(sourceDescriptions, { report, location }: UserContext) { + if (!sourceDescriptions.length) return; + for (const sourceDescription of sourceDescriptions) { if (!['openapi', 'arazzo'].includes(sourceDescription?.type)) { report({ message: 'The `type` property of the `sourceDescription` object must be either `openapi` or `arazzo`.', - location: location.child([SourceDescriptions.indexOf(sourceDescription)]), + location: location.child([sourceDescriptions.indexOf(sourceDescription)]), }); } } diff --git a/packages/core/src/rules/arazzo/sourceDescriptions-name-unique.ts b/packages/core/src/rules/arazzo/sourceDescriptions-name-unique.ts index aea5ae8758..6f679ca244 100644 --- a/packages/core/src/rules/arazzo/sourceDescriptions-name-unique.ts +++ b/packages/core/src/rules/arazzo/sourceDescriptions-name-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const SourceDescriptionsNameUnique: ArazzoRule = () => { +export const SourceDescriptionsNameUnique: Arazzo1Rule = () => { const seenSourceDescriptions = new Set(); return { diff --git a/packages/core/src/rules/arazzo/sourceDescriptions-not-empty.ts b/packages/core/src/rules/arazzo/sourceDescriptions-not-empty.ts new file mode 100644 index 0000000000..dbc929ab8b --- /dev/null +++ b/packages/core/src/rules/arazzo/sourceDescriptions-not-empty.ts @@ -0,0 +1,17 @@ +import type { Arazzo1Rule } from '../../visitors'; +import type { UserContext } from '../../walk'; + +export const SourceDescriptionsNotEmpty: Arazzo1Rule = () => { + return { + SourceDescriptions: { + enter(sourceDescriptions, { report, location }: UserContext) { + if (!sourceDescriptions?.length) { + report({ + message: 'The `sourceDescriptions` list must have at least one entry.', + location, + }); + } + }, + }, + }; +}; diff --git a/packages/core/src/rules/arazzo/step-onFailure-unique.ts b/packages/core/src/rules/arazzo/step-onFailure-unique.ts index 121240bb32..4b206426dc 100644 --- a/packages/core/src/rules/arazzo/step-onFailure-unique.ts +++ b/packages/core/src/rules/arazzo/step-onFailure-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const StepOnFailureUnique: ArazzoRule = () => { +export const StepOnFailureUnique: Arazzo1Rule = () => { return { OnFailureActionList: { enter(onFailureActionList, { report, location }: UserContext) { diff --git a/packages/core/src/rules/arazzo/step-onSuccess-unique.ts b/packages/core/src/rules/arazzo/step-onSuccess-unique.ts index 35ec98e169..1aab82bb5d 100644 --- a/packages/core/src/rules/arazzo/step-onSuccess-unique.ts +++ b/packages/core/src/rules/arazzo/step-onSuccess-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const StepOnSuccessUnique: ArazzoRule = () => { +export const StepOnSuccessUnique: Arazzo1Rule = () => { return { OnSuccessActionList: { enter(onSuccessActionList, { report, location }: UserContext) { diff --git a/packages/core/src/rules/arazzo/stepId-unique.ts b/packages/core/src/rules/arazzo/stepId-unique.ts index 037b5a321b..002b20814b 100644 --- a/packages/core/src/rules/arazzo/stepId-unique.ts +++ b/packages/core/src/rules/arazzo/stepId-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const StepIdUnique: ArazzoRule = () => { +export const StepIdUnique: Arazzo1Rule = () => { return { Workflow: { enter(workflow, { report, location }: UserContext) { diff --git a/packages/core/src/rules/arazzo/workflow-dependsOn.ts b/packages/core/src/rules/arazzo/workflow-dependsOn.ts index a324335e8b..5123540471 100644 --- a/packages/core/src/rules/arazzo/workflow-dependsOn.ts +++ b/packages/core/src/rules/arazzo/workflow-dependsOn.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const WorkflowDependsOn: ArazzoRule = () => { +export const WorkflowDependsOn: Arazzo1Rule = () => { const seenWorkflow = new Set(); const existingSourceDescriptions = new Set(); const existingWorkflowIds = new Set(); diff --git a/packages/core/src/rules/arazzo/workflowId-unique.ts b/packages/core/src/rules/arazzo/workflowId-unique.ts index fe0363f7bf..81b3c5b788 100644 --- a/packages/core/src/rules/arazzo/workflowId-unique.ts +++ b/packages/core/src/rules/arazzo/workflowId-unique.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const WorkflowIdUnique: ArazzoRule = () => { +export const WorkflowIdUnique: Arazzo1Rule = () => { const seenWorkflow = new Set(); return { diff --git a/packages/core/src/rules/async2/index.ts b/packages/core/src/rules/async2/index.ts index e91f33c86d..76752ed7ac 100644 --- a/packages/core/src/rules/async2/index.ts +++ b/packages/core/src/rules/async2/index.ts @@ -1,5 +1,5 @@ import { Assertions } from '../common/assertions'; -import { Spec } from '../common/spec'; +import { Struct } from '../common/struct'; import { InfoContact } from '../common/info-contact'; import { InfoLicenseStrict } from '../common/info-license-strict'; import { OperationOperationId } from '../common/operation-operationId'; @@ -12,7 +12,8 @@ import type { Async2Rule } from '../../visitors'; import type { Async2RuleSet } from '../../oas-types'; export const rules: Async2RuleSet<'built-in'> = { - spec: Spec as Async2Rule, + spec: Struct as Async2Rule, + struct: Struct as Async2Rule, assertions: Assertions as Async2Rule, 'info-contact': InfoContact as Async2Rule, 'info-license-strict': InfoLicenseStrict as Async2Rule, diff --git a/packages/core/src/rules/async3/index.ts b/packages/core/src/rules/async3/index.ts index 8bad38e4b2..471fb76d3f 100644 --- a/packages/core/src/rules/async3/index.ts +++ b/packages/core/src/rules/async3/index.ts @@ -1,5 +1,5 @@ import { Assertions } from '../common/assertions'; -import { Spec } from '../common/spec'; +import { Struct } from '../common/struct'; import { InfoContact } from '../common/info-contact'; import { InfoLicenseStrict } from '../common/info-license-strict'; import { OperationOperationId } from '../common/operation-operationId'; @@ -11,8 +11,10 @@ import { NoChannelTrailingSlash } from './no-channel-trailing-slash'; import type { Async3Rule } from '../../visitors'; import type { Async3RuleSet } from '../../oas-types'; + export const rules: Async3RuleSet<'built-in'> = { - spec: Spec as Async3Rule, + spec: Struct as Async3Rule, + struct: Struct as Async3Rule, assertions: Assertions as Async3Rule, 'info-contact': InfoContact as Async3Rule, 'info-license-strict': InfoLicenseStrict as Async3Rule, diff --git a/packages/core/src/rules/common/__tests__/no-enum-type-mismatch.test.ts b/packages/core/src/rules/common/__tests__/no-enum-type-mismatch.test.ts index f7cacf3e7a..f169a79735 100644 --- a/packages/core/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +++ b/packages/core/src/rules/common/__tests__/no-enum-type-mismatch.test.ts @@ -200,7 +200,7 @@ describe('Oas3 typed enum', () => { }, ], "message": "Expected type \`Schema\` (object) but got \`null\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, diff --git a/packages/core/src/rules/common/__tests__/spec.test.ts b/packages/core/src/rules/common/__tests__/struct.test.ts similarity index 92% rename from packages/core/src/rules/common/__tests__/spec.test.ts rename to packages/core/src/rules/common/__tests__/struct.test.ts index f1daa99c6f..0eec0d7c02 100644 --- a/packages/core/src/rules/common/__tests__/spec.test.ts +++ b/packages/core/src/rules/common/__tests__/struct.test.ts @@ -3,7 +3,7 @@ import { lintDocument } from '../../../lint'; import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils'; import { BaseResolver } from '../../../resolve'; -describe('Oas3 spec', () => { +describe('Oas3 struct', () => { it('should report missing schema property', async () => { const document = parseYamlToDocument( outdent` @@ -25,7 +25,7 @@ describe('Oas3 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -40,7 +40,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`info\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -54,7 +54,7 @@ describe('Oas3 spec', () => { }, ], "message": "Must contain at least one of the following fields: schema, content.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -85,7 +85,7 @@ describe('Oas3 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -100,7 +100,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`paths\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -114,7 +114,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`info\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -131,7 +131,7 @@ describe('Oas3 spec', () => { }, ], "message": "Property \`content\` is not expected here.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -157,7 +157,7 @@ describe('Oas3 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -172,7 +172,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`paths\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -186,7 +186,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`info\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -199,7 +199,7 @@ describe('Oas3 spec', () => { }, ], "message": "The \`type\` field must be defined when the \`nullable\` field is used.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -231,7 +231,7 @@ describe('Oas3 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -246,7 +246,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`paths\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -260,7 +260,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`info\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -273,7 +273,7 @@ describe('Oas3 spec', () => { }, ], "message": "The \`type\` field must be defined when the \`nullable\` field is used.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -287,7 +287,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`content\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -301,7 +301,7 @@ describe('Oas3 spec', () => { }, ], "message": "Property \`TestSchema\` is not expected here.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -322,7 +322,7 @@ describe('Oas3 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -337,7 +337,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`paths\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -351,7 +351,7 @@ describe('Oas3 spec', () => { }, ], "message": "The field \`info\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -360,7 +360,7 @@ describe('Oas3 spec', () => { }); }); -describe('Oas3.1 spec', () => { +describe('Oas3.1 struct', () => { it('should report with "type can be one of the following only"', async () => { const document = parseYamlToDocument( outdent` @@ -384,7 +384,7 @@ describe('Oas3.1 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -399,7 +399,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "\`type\` can be one of the following only: "object", "array", "string", "number", "integer", "boolean", "null".", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -432,7 +432,7 @@ describe('Oas3.1 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -447,7 +447,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "\`type\` can be one of the following only: "object", "array", "string", "number", "integer", "boolean", "null".", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -486,7 +486,7 @@ describe('Oas3.1 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -501,7 +501,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "\`type\` can be one of the following only: "object", "array", "string", "number", "integer", "boolean", "null".", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [ "object", @@ -523,7 +523,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "\`type\` can be one of the following only: "object", "array", "string", "number", "integer", "boolean", "null".", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [ "object", @@ -557,7 +557,7 @@ describe('Oas3.1 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -572,7 +572,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "Must contain at least one of the following fields: paths, components, webhooks.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -586,7 +586,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "The field \`title\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -600,7 +600,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "The field \`version\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -632,7 +632,7 @@ describe('Oas3.1 spec', () => { const results = await lintDocument({ externalRefResolver: new BaseResolver(), document, - config: await makeConfig({ rules: { spec: 'error' } }), + config: await makeConfig({ rules: { struct: 'error' } }), }); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` @@ -647,7 +647,7 @@ describe('Oas3.1 spec', () => { }, ], "message": "Expected type \`SchemaMap\` (object) but got \`array\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, diff --git a/packages/core/src/rules/common/spec.ts b/packages/core/src/rules/common/struct.ts similarity index 98% rename from packages/core/src/rules/common/spec.ts rename to packages/core/src/rules/common/struct.ts index 3c2dfece5e..d69697b17e 100644 --- a/packages/core/src/rules/common/spec.ts +++ b/packages/core/src/rules/common/struct.ts @@ -4,9 +4,9 @@ import { isRef } from '../../ref-utils'; import { isPlainObject } from '../../utils'; import type { UserContext } from '../../walk'; -import type { Oas3Rule, Oas2Rule, Async2Rule, Async3Rule, ArazzoRule } from '../../visitors'; +import type { Oas3Rule, Oas2Rule, Async2Rule, Async3Rule, Arazzo1Rule } from '../../visitors'; -export const Spec: Oas3Rule | Oas2Rule | Async2Rule | Async3Rule | ArazzoRule = () => { +export const Struct: Oas3Rule | Oas2Rule | Async2Rule | Async3Rule | Arazzo1Rule = () => { return { any( node: any, diff --git a/packages/core/src/rules/oas2/index.ts b/packages/core/src/rules/oas2/index.ts index 12c1575ffd..31d7e40cb3 100644 --- a/packages/core/src/rules/oas2/index.ts +++ b/packages/core/src/rules/oas2/index.ts @@ -1,4 +1,4 @@ -import { Spec } from '../common/spec'; +import { Struct } from '../common/struct'; import { NoInvalidSchemaExamples } from '../common/no-invalid-schema-examples'; import { NoInvalidParameterExamples } from '../common/no-invalid-parameter-examples'; import { InfoContact } from '../common/info-contact'; @@ -47,7 +47,8 @@ import type { Oas2Rule } from '../../visitors'; import type { Oas2RuleSet } from '../../oas-types'; export const rules: Oas2RuleSet<'built-in'> = { - spec: Spec as Oas2Rule, + spec: Struct as Oas2Rule, + struct: Struct as Oas2Rule, 'no-invalid-schema-examples': NoInvalidSchemaExamples, 'no-invalid-parameter-examples': NoInvalidParameterExamples, 'info-contact': InfoContact as Oas2Rule, diff --git a/packages/core/src/rules/oas3/__tests__/spec/spec.test.ts b/packages/core/src/rules/oas3/__tests__/spec/spec.test.ts index 6be1ab0c14..da401485bf 100644 --- a/packages/core/src/rules/oas3/__tests__/spec/spec.test.ts +++ b/packages/core/src/rules/oas3/__tests__/spec/spec.test.ts @@ -65,7 +65,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`string\` but got \`array\`.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -79,7 +79,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`string\` but got \`boolean\`.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -93,7 +93,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`License\` (object) but got \`string\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -124,7 +124,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`string\` but got \`integer\`.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -138,7 +138,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`Tag\` (object) but got \`number\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -152,7 +152,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Expected type \`Tag\` (object) but got \`string\`", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -199,7 +199,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Property \`components1\` is not expected here.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [ "components", @@ -228,7 +228,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "Property \`test\` is not expected here.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -270,7 +270,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "The field \`paths\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, @@ -297,7 +297,7 @@ describe('Oas3 Structural visitor basic', () => { }, ], "message": "The field \`title\` must be present on this level.", - "ruleId": "spec", + "ruleId": "struct", "severity": "error", "suggest": [], }, diff --git a/packages/core/src/rules/oas3/index.ts b/packages/core/src/rules/oas3/index.ts index 43845b2bfe..22092b2b9c 100644 --- a/packages/core/src/rules/oas3/index.ts +++ b/packages/core/src/rules/oas3/index.ts @@ -1,4 +1,4 @@ -import { Spec } from '../common/spec'; +import { Struct } from '../common/struct'; import { Operation2xxResponse } from '../common/operation-2xx-response'; import { Operation4xxResponse } from '../common/operation-4xx-response'; import { Assertions } from '../common/assertions'; @@ -59,7 +59,8 @@ import type { Oas3RuleSet } from '../../oas-types'; import type { Oas3Rule } from '../../visitors'; export const rules: Oas3RuleSet<'built-in'> = { - spec: Spec as Oas3Rule, + spec: Struct as Oas3Rule, + struct: Struct as Oas3Rule, 'info-contact': InfoContact as Oas3Rule, 'info-license': InfoLicense as Oas3Rule, 'info-license-url': InfoLicenseUrl as Oas3Rule, diff --git a/packages/core/src/rules/spot/no-actions-type-end.ts b/packages/core/src/rules/spot/no-actions-type-end.ts index f0e816d205..8383e9890a 100644 --- a/packages/core/src/rules/spot/no-actions-type-end.ts +++ b/packages/core/src/rules/spot/no-actions-type-end.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const NoActionsTypeEnd: ArazzoRule = () => { +export const NoActionsTypeEnd: Arazzo1Rule = () => { return { FailureActionObject: { enter(action, { report, location }: UserContext) { diff --git a/packages/core/src/rules/spot/no-criteria-xpath.ts b/packages/core/src/rules/spot/no-criteria-xpath.ts index dac5a950eb..b45839ccdd 100644 --- a/packages/core/src/rules/spot/no-criteria-xpath.ts +++ b/packages/core/src/rules/spot/no-criteria-xpath.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const NoCriteriaXpath: ArazzoRule = () => { +export const NoCriteriaXpath: Arazzo1Rule = () => { return { CriterionObject: { enter(criteria, { report, location }: UserContext) { diff --git a/packages/core/src/rules/spot/parameters-not-in-body.ts b/packages/core/src/rules/spot/parameters-not-in-body.ts index 0717751f24..4b4ef3e437 100644 --- a/packages/core/src/rules/spot/parameters-not-in-body.ts +++ b/packages/core/src/rules/spot/parameters-not-in-body.ts @@ -1,7 +1,7 @@ -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const ParametersNotInBody: ArazzoRule = () => { +export const ParametersNotInBody: Arazzo1Rule = () => { return { Parameter: { enter(parameter, { report, location }: UserContext) { diff --git a/packages/core/src/rules/spot/version-enum.ts b/packages/core/src/rules/spot/version-enum.ts index 12c352c5fa..c19e099e19 100644 --- a/packages/core/src/rules/spot/version-enum.ts +++ b/packages/core/src/rules/spot/version-enum.ts @@ -1,10 +1,10 @@ import { ARAZZO_VERSIONS_SUPPORTED_BY_SPOT } from '../../typings/arazzo'; import { pluralize } from '../../utils'; -import type { ArazzoRule } from '../../visitors'; +import type { Arazzo1Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const VersionEnum: ArazzoRule = () => { +export const VersionEnum: Arazzo1Rule = () => { const supportedVersions = ARAZZO_VERSIONS_SUPPORTED_BY_SPOT.join(', '); return { Root: { diff --git a/packages/core/src/types/arazzo.ts b/packages/core/src/types/arazzo.ts index df67e7085a..78df3ba3d9 100755 --- a/packages/core/src/types/arazzo.ts +++ b/packages/core/src/types/arazzo.ts @@ -50,10 +50,8 @@ const SourceDescriptions: NodeType = { items: (value: any) => { if (value?.type === 'openapi') { return 'OpenAPISourceDescription'; - } else if (value?.type === 'arazzo') { - return 'ArazzoSourceDescription'; } else { - return 'NoneSourceDescription'; + return 'ArazzoSourceDescription'; } }, }; @@ -67,15 +65,6 @@ const OpenAPISourceDescription: NodeType = { required: ['name', 'type', 'url'], extensionsPrefix: 'x-', }; -const NoneSourceDescription: NodeType = { - properties: { - name: { type: 'string' }, - type: { type: 'string', enum: ['none'] }, - 'x-serverUrl': { type: 'string' }, - }, - required: ['name', 'type', 'x-serverUrl'], - extensionsPrefix: 'x-', -}; const ArazzoSourceDescription: NodeType = { properties: { name: { type: 'string' }, @@ -283,12 +272,11 @@ const OnFailureActionList: NodeType = { }, }; -export const ArazzoTypes: Record = { +export const Arazzo1Types: Record = { Root, Info, SourceDescriptions, OpenAPISourceDescription, - NoneSourceDescription, ArazzoSourceDescription, Parameters, Parameter, diff --git a/packages/core/src/types/redocly-yaml.ts b/packages/core/src/types/redocly-yaml.ts index dc8675ef63..9ae3109757 100644 --- a/packages/core/src/types/redocly-yaml.ts +++ b/packages/core/src/types/redocly-yaml.ts @@ -8,8 +8,11 @@ import type { JSONSchema } from 'json-schema-to-ts'; import type { NodeType } from '.'; import type { Config } from '../config'; +const builtInCommonRules = ['struct'] as const; + const builtInCommonOASRules = [ 'spec', + 'struct', 'info-contact', 'operation-operationId', 'tag-description', @@ -51,9 +54,55 @@ const builtInCommonOASRules = [ 'no-required-schema-properties-undefined', ] as const; + +const builtInCommonArazzoRules = [ + 'struct', +] as const; + export type BuiltInCommonOASRuleId = typeof builtInCommonOASRules[number]; +export type BuiltInCommonRuleId = typeof builtInCommonRules[number]; +export type BuiltInCommonArazzoRuleId = typeof builtInCommonArazzoRules[number]; const builtInOAS2Rules = [ + 'info-contact', + 'info-license', + 'info-license-url', + 'info-license-strict', + 'tag-description', + 'tags-alphabetical', + 'parameter-description', + 'path-declaration-must-exist', + 'path-not-include-query', + 'path-parameters-defined', + 'paths-kebab-case', + 'path-excludes-patterns', + 'path-http-verbs-order', + 'path-params-defined', + 'path-segment-plural', + 'operation-summary', + 'operation-operationId', + 'operation-operationId-unique', + 'operation-operationId-url-safe', + 'operation-description', + 'operation-2xx-response', + 'operation-4xx-response', + 'operation-parameters-unique', + 'operation-tag-defined', + 'operation-singular-tag', + 'required-string-property-missing-min-length', + 'response-contains-header', + 'security-defined', + 'spec-strict-refs', + 'scalar-property-missing-example', + 'no-identical-paths', + 'no-path-trailing-slash', + 'no-ambiguous-paths', + 'no-invalid-schema-examples', + 'no-invalid-parameter-examples', + 'no-http-verbs-in-paths', + 'no-enum-type-mismatch', + 'no-unresolved-refs', + 'no-required-schema-properties-undefined', 'boolean-parameter-prefixes', 'request-mime-type', 'response-contains-property', @@ -63,6 +112,45 @@ const builtInOAS2Rules = [ export type BuiltInOAS2RuleId = typeof builtInOAS2Rules[number]; const builtInOAS3Rules = [ + 'info-contact', + 'info-license', + 'info-license-url', + 'info-license-strict', + 'tag-description', + 'tags-alphabetical', + 'parameter-description', + 'path-declaration-must-exist', + 'path-not-include-query', + 'path-parameters-defined', + 'paths-kebab-case', + 'path-excludes-patterns', + 'path-http-verbs-order', + 'path-params-defined', + 'path-segment-plural', + 'operation-summary', + 'operation-operationId', + 'operation-operationId-unique', + 'operation-operationId-url-safe', + 'operation-description', + 'operation-2xx-response', + 'operation-4xx-response', + 'operation-parameters-unique', + 'operation-tag-defined', + 'operation-singular-tag', + 'required-string-property-missing-min-length', + 'response-contains-header', + 'security-defined', + 'spec-strict-refs', + 'scalar-property-missing-example', + 'no-identical-paths', + 'no-path-trailing-slash', + 'no-ambiguous-paths', + 'no-invalid-schema-examples', + 'no-invalid-parameter-examples', + 'no-http-verbs-in-paths', + 'no-enum-type-mismatch', + 'no-unresolved-refs', + 'no-required-schema-properties-undefined', 'boolean-parameter-prefixes', 'component-name-unique', 'no-empty-servers', @@ -83,8 +171,12 @@ const builtInOAS3Rules = [ export type BuiltInOAS3RuleId = typeof builtInOAS3Rules[number]; -const builtInAsync2Rules = [ +const builtInCommonAsyncRules = [ 'spec', + 'struct', +]; + +const builtInAsync2Rules = [ 'info-contact', 'info-license-strict', 'operation-operationId', @@ -95,7 +187,6 @@ const builtInAsync2Rules = [ ] as const; const builtInAsync3Rules = [ - 'spec', 'info-contact', 'info-license-strict', 'operation-operationId', @@ -109,14 +200,16 @@ export type BuiltInAsync2RuleId = typeof builtInAsync2Rules[number]; export type BuiltInAsync3RuleId = typeof builtInAsync3Rules[number]; -const builtInArazzoRules = [ - 'spec', +export type BuiltInCommonAsyncRuleId = typeof builtInCommonAsyncRules[number]; + +const builtInArazzo1Rules = [ 'parameters-not-in-body', 'sourceDescription-type', 'version-enum', 'workflowId-unique', 'stepId-unique', 'sourceDescription-name-unique', + 'sourceDescriptions-not-empty', 'workflow-dependsOn', 'parameters-unique', 'step-onSuccess-unique', @@ -127,15 +220,17 @@ const builtInArazzoRules = [ 'criteria-unique', ] as const; -export type BuiltInArazzoRuleId = typeof builtInArazzoRules[number]; +export type BuiltInArazzo1RuleId = typeof builtInArazzo1Rules[number]; const builtInRules = [ ...builtInCommonOASRules, + ...builtInCommonArazzoRules, ...builtInOAS2Rules, ...builtInOAS3Rules, ...builtInAsync2Rules, ...builtInAsync3Rules, - ...builtInArazzoRules, + ...builtInArazzo1Rules, + 'spec', ] as const; type BuiltInRuleId = typeof builtInRules[number]; @@ -278,7 +373,7 @@ const ConfigStyleguide: NodeType = { oas3_0Rules: 'Rules', oas3_1Rules: 'Rules', async2Rules: 'Rules', - arazzoRules: 'Rules', + arazzo1Rules: 'Rules', preprocessors: { type: 'object' }, oas2Preprocessors: { type: 'object' }, oas3_0Preprocessors: { type: 'object' }, @@ -290,7 +385,7 @@ const ConfigStyleguide: NodeType = { oas3_0Decorators: { type: 'object' }, oas3_1Decorators: { type: 'object' }, async2Decorators: { type: 'object' }, - arazzoDecorators: { type: 'object' }, + arazzo1Decorators: { type: 'object' }, }, }; diff --git a/packages/core/src/typings/arazzo.ts b/packages/core/src/typings/arazzo.ts index 77037f5e5c..d0c71365a1 100644 --- a/packages/core/src/typings/arazzo.ts +++ b/packages/core/src/typings/arazzo.ts @@ -12,22 +12,13 @@ export interface OpenAPISourceDescription { 'x-serverUrl'?: string; } -export interface NoneSourceDescription { - name: string; - type: 'none'; - 'x-serverUrl': string; -} - export interface ArazzoSourceDescription { name: string; type: 'arazzo'; url: string; } -export type SourceDescription = - | OpenAPISourceDescription - | NoneSourceDescription - | ArazzoSourceDescription; +export type SourceDescription = OpenAPISourceDescription | ArazzoSourceDescription; export interface Parameter { in?: 'header' | 'query' | 'path' | 'cookie' | 'body'; diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index bce689d998..6b6d0476e3 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -244,14 +244,16 @@ export function doesYamlFileExist(filePath: string): boolean { export function showWarningForDeprecatedField( deprecatedField: string, updatedField?: string, - updatedObject?: string + updatedObject?: string, + link?: string ) { + const readMoreText = link ? `Read more about this change: ${link}` : ''; logger.warn( `The '${colorize.red(deprecatedField)}' field is deprecated. ${ updatedField ? `Use ${colorize.green(getUpdatedFieldName(updatedField, updatedObject))} instead. ` : '' - }Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n` + }${readMoreText}\n` ); } diff --git a/packages/core/src/visitors.ts b/packages/core/src/visitors.ts index ac7aa00cab..445fa1e7f3 100644 --- a/packages/core/src/visitors.ts +++ b/packages/core/src/visitors.ts @@ -58,7 +58,6 @@ import type { ExpectSchema, ExtendedOperation, InfoObject, - NoneSourceDescription, OnFailureObject, OnSuccessObject, OpenAPISourceDescription, @@ -240,7 +239,6 @@ type ArazzoFlatVisitor = { ParameterObject?: VisitFunctionOrObject; InfoObject?: VisitFunctionOrObject; OpenAPISourceDescription?: VisitFunctionOrObject; - NoneSourceDescription?: VisitFunctionOrObject; ArazzoSourceDescription?: VisitFunctionOrObject; SourceDescription?: VisitFunctionOrObject; ExtendedOperation?: VisitFunctionOrObject; @@ -348,17 +346,17 @@ export type Oas3Rule = (options: Record) => Oas3Visitor | Oas3Visit export type Oas2Rule = (options: Record) => Oas2Visitor | Oas2Visitor[]; export type Async2Rule = (options: Record) => Async2Visitor | Async2Visitor[]; export type Async3Rule = (options: Record) => Async3Visitor | Async3Visitor[]; -export type ArazzoRule = (options: Record) => ArazzoVisitor | ArazzoVisitor[]; +export type Arazzo1Rule = (options: Record) => ArazzoVisitor | ArazzoVisitor[]; export type Oas3Preprocessor = (options: Record) => Oas3Visitor; export type Oas2Preprocessor = (options: Record) => Oas2Visitor; export type Async2Preprocessor = (options: Record) => Async2Visitor; export type Async3Preprocessor = (options: Record) => Async3Visitor; -export type ArazzoPreprocessor = (options: Record) => ArazzoVisitor; +export type Arazzo1Preprocessor = (options: Record) => ArazzoVisitor; export type Oas3Decorator = (options: Record) => Oas3Visitor; export type Oas2Decorator = (options: Record) => Oas2Visitor; export type Async2Decorator = (options: Record) => Async2Visitor; export type Async3Decorator = (options: Record) => Async3Visitor; -export type ArazzoDecorator = (options: Record) => ArazzoVisitor; +export type Arazzo1Decorator = (options: Record) => ArazzoVisitor; // alias for the latest version supported // every time we update it - consider semver