diff --git a/docs/guides/lint-arazzo.md b/docs/guides/lint-arazzo.md index 1efa1e22c..a5ea1503a 100644 --- a/docs/guides/lint-arazzo.md +++ b/docs/guides/lint-arazzo.md @@ -71,22 +71,7 @@ run `redocly lint --generate-ignore-file` to add all problems to the ignore file ## Configure the linting rules Choose from the ready-made rulesets (`minimal`, `recommended` or `recommended-strict`), or go one better and configure the rules that suit your use case. -The rules available for linting Arazzo are: - -- `parameters-not-in-body`: the `in` section inside `parameters` must not contain a `body`. -- `sourceDescription-type`: the `type` property of the `sourceDescription` object must be either `openapi` or `arazzo`. -- `version-enum`: the `version` property must be one of the supported values. -- `workflowId-unique`: the `workflowId` property must be unique across all workflows. -- `stepId-unique`: the `stepId` must be unique amongst all steps described in the workflow. -- `sourceDescription-name-unique`: the `name` property of the `sourceDescription` object must be unique across all source descriptions. -- `workflow-dependsOn`: the items in the `workflow` `dependsOn` property must exist and be unique. -- `parameters-unique`: the `parameters` list must not include duplicate parameters. -- `step-onSuccess-unique`: the `onSuccess` actions of the `step` object must be unique. -- `step-onFailure-unique`: the `onFailure` actions of the `step` object must be unique. -- `requestBody-replacements-unique`: the `replacements` of the `requestBody` object must be unique. -- `no-criteria-xpath`: the `xpath` type criteria is not supported by Spot. -- `no-actions-type-end`: the `end` type action is not supported by Spot. -- `criteria-unique`: the criteria list must not contain duplicated assertions. +There's a full [list of built-in rules for Arazzo](../rules/built-in-rules.md#arazzo-rules) to refer to. Add the rules to `redocly.yaml`, but for Arazzo specifications, the rules go in their own configuration section called `arazzoRules`. The following example shows configuration for the minimal ruleset with some additional rules configuration: @@ -96,7 +81,7 @@ extends: - minimal arazzoRules: - sourceDescription-name-unique: warn + sourceDescriptions-name-unique: warn version-enum: error ``` diff --git a/docs/guides/lint-asyncapi.md b/docs/guides/lint-asyncapi.md index 9de216818..6eeb4732b 100644 --- a/docs/guides/lint-asyncapi.md +++ b/docs/guides/lint-asyncapi.md @@ -53,8 +53,8 @@ some of the built-in rules. The currently-supported rules are: - `info-contact`: the `Info` section must contain a valid `Contact` field. - `operation-operationId`: every operation must have a valid `operationId`. -- `channels-kebab-case`: channel names should be `kebab-case` (lowercase with hyphens). -- `no-channel-trailing-slash`: channel names must not have trailing slashes in their names. +- `channels-kebab-case`: channel address should be `kebab-case` (lowercase with hyphens). +- `no-channel-trailing-slash`: channel names must not have trailing slashes in their address. - `tag-description`: all tags require a description. - `tags-alphabetical`: tags should be listed in the AsyncAPI file in alphabetical order. diff --git a/docs/rules/arazzo/criteria-unique.md b/docs/rules/arazzo/criteria-unique.md index 9cff899c3..08ef66e8e 100644 --- a/docs/rules/arazzo/criteria-unique.md +++ b/docs/rules/arazzo/criteria-unique.md @@ -1,7 +1,3 @@ ---- -slug: /docs/cli/rules/arazzo/criteria-unique ---- - # criteria-unique The criteria list must not contain duplicated assertions. @@ -10,9 +6,9 @@ The criteria list must not contain duplicated assertions. | ------ | ------------- | | 1.0.0 | ✅ | -## API design principles +## Design principles -The criteria list must not contain duplicated assertions. +To avoid redundancy and confusion, the assertions in the criteria list must not be duplicated. ## Configuration @@ -23,7 +19,7 @@ The criteria list must not contain duplicated assertions. An example configuration: ```yaml -arazzoRules: +rules: criteria-unique: error ``` @@ -32,7 +28,7 @@ arazzoRules: Given the following configuration: ```yaml -arazzoRules: +rules: criteria-unique: error ``` diff --git a/docs/rules/arazzo/parameters-unique.md b/docs/rules/arazzo/parameters-unique.md new file mode 100644 index 000000000..5748de4a3 --- /dev/null +++ b/docs/rules/arazzo/parameters-unique.md @@ -0,0 +1,72 @@ +# parameters-unique + +Requires unique values in the `parameters` lists. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +A list of `parameters` that are applicable to a step or all the steps described in a workflow should not contain duplicates. +If duplicates are present, unexpected parameter overrides could cause problems. + +This ruled checks parameter lists in the following locations: + +- `workflows.[workflow].parameters` +- `workflows.[workflow[.steps.[step].parameters` +- `x-parameters` + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + parameters-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + parameters-unique: error +``` + +Example of an **incorrect** `parameters` list: + +```yaml Incorrect example +workflows: + - workflowId: get-museum-hours + parameters: + - in: header + name: Authorization + value: Main Og== + - in: header + name: Authorization + value: Basic Og== +``` + +Example of a **correct** `parameters` list: + +```yaml Correct example +workflows: + - workflowId: get-museum-hours + parameters: + - in: header + name: Authorization + value: Basic Og== + - in: header + name: X-Forwarded-For + value: 1.2.3.4 +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/parameters-unique.ts) diff --git a/docs/rules/arazzo/requestBody-replacements-unique.md b/docs/rules/arazzo/requestBody-replacements-unique.md new file mode 100644 index 000000000..b1093d22a --- /dev/null +++ b/docs/rules/arazzo/requestBody-replacements-unique.md @@ -0,0 +1,75 @@ +# requestBody-replacements-unique + +Requires the `replacements` in the `step.requestBody` object to be unique. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +The list of locations and values to set within a payload must not have duplicates that might result in content override. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + requestBody-replacements-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + requestBody-replacements-unique: error +``` + +Example of an **incorrect** `replacements` list: + +```yaml Incorrect example +workflows: + - workflowId: events-crud + steps: + - stepId: create-event + operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post + requestBody: + payload: + name: 'Mermaid Treasure Identification and Analysis' + description: 'Identify and analyze mermaid treasures' + replacements: + - target: name + value: 'new name' + - target: name + value: 'another name' +``` + +Example of a **correct** `replacements` list: + +```yaml Correct example +workflows: + - workflowId: events-crud + steps: + - stepId: create-event + operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post + requestBody: + payload: + name: 'Mermaid Treasure Identification and Analysis' + description: 'Identify and analyze mermaid treasures' + replacements: + - target: name + value: 'new name' + - target: description + value: 'another description' +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/requestBody-replacements-unique.ts) diff --git a/docs/rules/arazzo/sourceDescriptions-name-unique.md b/docs/rules/arazzo/sourceDescriptions-name-unique.md new file mode 100644 index 000000000..892bb0241 --- /dev/null +++ b/docs/rules/arazzo/sourceDescriptions-name-unique.md @@ -0,0 +1,66 @@ +# sourceDescriptions-name-unique + +The `name` property of the Source Description object must be unique across all source descriptions. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +To avoid confusion or unexpected outputs, each Source Description object should have a unique `name` property. +Especially in a longer list of sources, this could be difficult to identify and could have unwanted side effects. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + sourceDescriptions-name-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + sourceDescriptions-name-unique: error +``` + +Example of an **incorrect** `sourceDescriptions` list: + +```yaml Incorrect example +sourceDescriptions: + - name: museum-api + type: openapi + url: ../openapi.yaml + - name: museum-api + type: openapi + url: ../petstore.yaml +``` + +Example of a **correct** `sourceDescriptions` list: + +```yaml Correct example +sourceDescriptions: + - name: museum-api + type: openapi + url: ../openapi.yaml + - name: pets-api + type: openapi + url: ../petstore.yaml +``` + +## Related rules + +- [sourceDescription-type](./sourceDescriptions-type.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/sourceDescriptions-name-unique.ts) diff --git a/docs/rules/arazzo/sourceDescriptions-not-empty.md b/docs/rules/arazzo/sourceDescriptions-not-empty.md new file mode 100644 index 000000000..16ce2c55c --- /dev/null +++ b/docs/rules/arazzo/sourceDescriptions-not-empty.md @@ -0,0 +1,94 @@ +# sourceDescriptions-not-empty + +The Source Description must have at least one entry. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +Source descriptions are an important part of an Arazzo description, and at least one entry must exist. +If the list is empty, this could indicate an omission or another problem; this rule alerts you if that happens. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + sourceDescriptions-not-empty: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + sourceDescriptions-not-empty: error +``` + +Example of an **incorrect** usage: + +```yaml Incorrect example +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: $sourceDescriptions.museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +Example of a **correct** usage: + +```yaml Correct example +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: another-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: $sourceDescriptions.museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/sourceDescriptions-not-empty.ts) diff --git a/docs/rules/arazzo/sourceDescriptions-type.md b/docs/rules/arazzo/sourceDescriptions-type.md new file mode 100644 index 000000000..0b0641e14 --- /dev/null +++ b/docs/rules/arazzo/sourceDescriptions-type.md @@ -0,0 +1,66 @@ +# sourceDescriptions-type + +The `type` property of the Source Description object must be either `openapi` or `arazzo`. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +Arazzo currently supports either an OpenAPI file or another Arazzo file as the source description. +This rule makes sure that the type is clearly identified and is one of the supported types. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + sourceDescriptions-type: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + sourceDescriptions-type: error +``` + +Example of an **incorrect** `sourceDescriptions` list: + +```yaml Incorrect example +sourceDescriptions: + - name: museum-api + type: openapi + url: ../openapi.yaml + - name: tickets-from-museum-api + type: none + x-serverUrl: 'http://localhost/api' +``` + +Example of a **correct** `sourceDescriptions` list: + +```yaml Correct example +sourceDescriptions: + - name: museum-api + type: openapi + url: ../openapi.yaml + - name: tickets-from-museum-api + type: arazzo + url: museum-tickets.arazzo.yaml +``` + +## Related rules + +- [sourceDescription-name-unique](./sourceDescriptions-name-unique.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/sourceDescription-type.ts) diff --git a/docs/rules/arazzo/step-onFailure-unique.md b/docs/rules/arazzo/step-onFailure-unique.md new file mode 100644 index 000000000..2911951e7 --- /dev/null +++ b/docs/rules/arazzo/step-onFailure-unique.md @@ -0,0 +1,86 @@ +# step-onFailure-unique + +Requires all of the `onFailure` actions of the `step` object to be unique. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +Each `onFailure` action should be unique to avoid confusion or unexpected results. +A duplicate could indicate a mistake, or cause unwanted side effects if not detected by this rule. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + step-onFailure-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + step-onFailure-unique: error +``` + +Example of an **incorrect** `onFailure` list: + +```yaml Incorrect example +workflows: +- workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + onFailure: + - name: test + workflowId: events-crud + type: goto + - name: test + workflowId: events-crud + type: goto + - reference: $components.failureActions.notify + - reference: $components.failureActions.notify +``` + +Example of a **correct** `onFailure` list: + +```yaml Correct example +workflows: +- workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + onFailure: + - name: call-crud-events + workflowId: events-crud + type: goto + - name: second-call-crud-events + workflowId: events-crud + type: goto + - reference: $components.failureActions.notify + - reference: $components.failureActions.report +``` + +## Related rules + +- [step-onSuccess-unique](./step-onSuccess-unique.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/step-onFailure-unique.ts) diff --git a/docs/rules/arazzo/step-onSuccess-unique.md b/docs/rules/arazzo/step-onSuccess-unique.md new file mode 100644 index 000000000..08eb5942c --- /dev/null +++ b/docs/rules/arazzo/step-onSuccess-unique.md @@ -0,0 +1,86 @@ +# step-onSuccess-unique + +Requires the `onSuccess` actions of the `step` object to be unique. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +Each `onSuccess` action should be unique to avoid confusion or unexpected outcomes. +A duplicate could indicate a mistake, or cause unwanted side effects if not detected by this rule. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + step-onSuccess-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + step-onSuccess-unique: error +``` + +Example of an **incorrect** `onSuccess` list: + +```yaml Incorrect example +workflows: +- workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + onSuccess: + - name: test + workflowId: events-crud + type: goto + - name: test + workflowId: events-crud + type: goto + - reference: $components.successActions.notify + - reference: $components.successActions.notify +``` + +Example of a **correct** `onSuccess` list: + +```yaml Correct example +workflows: +- workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + onSuccess: + - name: call-crud-events + workflowId: events-crud + type: goto + - name: second-call-crud-events + workflowId: events-crud + type: goto + - reference: $components.successActions.notify + - reference: $components.successActions.report +``` + +## Related rules + +- [step-onFailure-unique](./step-onFailure-unique.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/step-onSuccess-unique.ts) diff --git a/docs/rules/arazzo/stepId-unique.md b/docs/rules/arazzo/stepId-unique.md new file mode 100644 index 000000000..90949aa71 --- /dev/null +++ b/docs/rules/arazzo/stepId-unique.md @@ -0,0 +1,74 @@ +# stepId-unique + +Requires the `stepId` to be unique amongst all steps described in the workflow. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +The steps in a workflow each have a required `stepId` field and this must be unique in order to conform with the specification. +This rule catches any accidental duplication of `stepId` values so that the workflow is valid. + +Note: `stepId` values are considered to be case-sensitive. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + stepId-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + stepId-unique: error +``` + +Example of an **incorrect** `stepId`: + +```yaml Incorrect example +workflows: + - workflowId: get-museum-hours-2 + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +Example of a **correct** `stepId`: + +```yaml Correct example +workflows: + - workflowId: get-museum-hours-2 + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + - stepId: another-step-id + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/stepId-unique.ts) diff --git a/docs/rules/arazzo/workflow-dependsOn.md b/docs/rules/arazzo/workflow-dependsOn.md new file mode 100644 index 000000000..666ff4f95 --- /dev/null +++ b/docs/rules/arazzo/workflow-dependsOn.md @@ -0,0 +1,60 @@ +# workflow-dependsOn + +Requires the items in the `workflow` `dependsOn` property to exist and to be unique. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +To avoid ambiguity or potential clashes, the `dependsOn` list values should be unique. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + workflow-dependsOn: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + workflow-dependsOn: error +``` + +Example of an **incorrect** `dependsOn` list: + +```yaml Incorrect example +workflows: + - workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + dependsOn: + - get-museum-hours-2 + - get-museum-hours-3 + - get-museum-hours-2 +``` + +Example of a **correct** `dependsOn` list: + +```yaml Correct example +workflows: + - workflowId: get-museum-hours + description: This workflow demonstrates how to get the museum opening hours and buy tickets. + dependsOn: + - get-museum-hours-2 + - get-museum-hours-3 +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/workflow-dependsOn.ts) diff --git a/docs/rules/arazzo/workflowId-unique.md b/docs/rules/arazzo/workflowId-unique.md new file mode 100644 index 000000000..208248e97 --- /dev/null +++ b/docs/rules/arazzo/workflowId-unique.md @@ -0,0 +1,74 @@ +# workflowId-unique + +Requires the `workflowId` property to be unique across all workflows. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## Design principles + +According to the spec, the `workflowId` must be unique across all workflows described in the API description. +Duplication could also indicate a typo or other mistake; this rule alerts you if such a situation arises. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +rules: + workflowId-unique: error +``` + +## Examples + +Given the following configuration: + +```yaml +rules: + workflowId-unique: error +``` + +Example of an **incorrect** `workflows` list: + +```yaml Incorrect example +workflows: + - workflowId: get-museum-hours + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + - workflowId: get-museum-hours + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +Example of a **correct** `workflows` list: + +```yaml Correct example +workflows: + - workflowId: get-museum-hours + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 + - workflowId: get-museum-hours-routine + steps: + - stepId: get-museum-hours + operationId: museum-api.getMuseumHours + successCriteria: + - condition: $statusCode == 200 +``` + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/arazzo/workflowId-unique.ts) diff --git a/docs/rules/async/channels-kebab-case.md b/docs/rules/async/channels-kebab-case.md new file mode 100644 index 000000000..84be0f4b1 --- /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 000000000..49804e5a5 --- /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 93576ce6b..5da31a89b 100644 --- a/docs/rules/built-in-rules.md +++ b/docs/rules/built-in-rules.md @@ -4,7 +4,7 @@ slug: /docs/cli/rules/built-in-rules # Built-in rules -The built-in rules are the ones we use ourselves and think apply to the majority of APIs. Some have some additional [configuration](#rule-configuration-syntax), but otherwise all you need to do is decide whether each rule should `error`, `warn` or be `off`. +The built-in rules are the ones we use ourselves and think apply to the majority of APIs. Some have some additional [configuration](./configure-rules.md), but otherwise all you need to do is decide whether each rule should `error`, `warn` or be `off`. All the built-in rules are listed here, roughly grouped by the OpenAPI object they apply to. The _Special rules_ group contains rules that may apply to multiple objects or to the entire OpenAPI document. @@ -13,9 +13,19 @@ The _Special rules_ group contains rules that may apply to multiple objects or t Build [configurable rules](./configurable-rules.md) if the rule you need isn't listed. {% /admonition %} -## List of available rules +## Rules for each API description format -Details of all the rules available "out of the box" with Redocly CLI are listed below. Visit each individual page for details of what the rule does, additional configuration options, and examples of it in use. +Redocly CLI can lint multiple API description formats: + +- [OpenAPI](#openapi-rules) +- [AsyncAPI](#asyncapi-rules) +- [Arazzo](#arazzo-rules) + +Visit each page for details of what the rule does, additional configuration options, and examples of it in use. + +## OpenAPI rules + +The rules list is split into sections. ### Special rules @@ -45,6 +55,7 @@ Details of all the rules available "out of the box" with Redocly CLI are listed ### Parameters +- [array-parameter-serialization](./array-parameter-serialization.md): Require `style` and `explode` for parameters with array type - [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 @@ -65,10 +76,12 @@ Details of all the rules available "out of the box" with Redocly CLI are listed ### Requests, Responses, and Schemas +- [component-name-unique](./component-name-unique.md): Check for schema-wide unqiue naming of parameters, schemas, request bodies and responses - [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 +- [no-required-schema-properties-undefined](./no-required-schema-properties-undefined.md): All properties marked as required must be defined - [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 @@ -91,43 +104,41 @@ Details of all the rules available "out of the box" with Redocly CLI are listed - [tag-description](./tag-description.md): Tags must have descriptions - [tags-alphabetical](./tags-alphabetical.md): Tags in the top-level `tags` section must appear alphabetically -## Rule configuration syntax +## AsyncAPI rules + +Use the rules in this section for AsyncAPI-specific linting. +Other rules such as the `spec` and `info.*` rules also apply to AsyncAPI. -To change your settings for any given rule, add or modify its corresponding entry in your Redocly configuration file. +- [channels-kebab-case](./async/channels-kebab-case.md): Channels must be in `kebab-case` format +- [no-channel-trailing-slash](./async/no-channel-trailing-slash.md): No trailing slashes on channels -You can specify global settings in the top-level `rules` object, or use per-API settings by adding a `rules` object under each API in `apis`. +## Arazzo rules -You can format each entry in the `rules` object in one of the following ways: +Within the Arazzo family of rules, there are rules for the main Arazzo specification format, and some additional rules for extensions supported by Spot, the Redocly testing utility. -- Short syntax with single-line configuration `rule-name: {severity}`, where `{severity}` is one of `error`, `warn` or `off`. You can't configure additional rule options with this syntax. +### Arazzo -```yaml -apis: - main: - root: ./openapi/openapi.yaml - rules: - specific-api-rule: warn -rules: - example-rule-name: error -``` +- [criteria-unique](./arazzo/criteria-unique.md): the criteria list must not contain duplicated assertions +- [parameters-unique](./arazzo/parameters-unique.md): the `parameters` list must not include duplicate parameters +- [requestBody-replacements-unique](./arazzo/requestBody-replacements-unique.md): the `replacements` of the `requestBody` object must be unique +- [sourceDescriptions-name-unique](./arazzo/sourceDescriptions-name-unique.md): the `name` property of the `sourceDescription` object must be unique across all source descriptions +- [sourceDescriptions-type](./arazzo/sourceDescriptions-type.md): the `type` property of the `sourceDescription` object must be either `openapi` or `arazzo` +- [stepId-unique](./arazzo/stepId-unique.md): the `stepId` must be unique amongst all steps described in the workflow +- [step-onFailure-unique](./arazzo/step-onFailure-unique.md): the `onFailure` actions of the `step` object must be unique +- [step-onSuccess-unique](./arazzo/step-onSuccess-unique.md): the `onSuccess` actions of the `step` object must be unique +- [workflow-dependsOn](./arazzo/workflow-dependsOn.md): the items in the `workflow` `dependsOn` property must exist and be unique +- [workflowId-unique](./arazzo/workflowId-unique.md): the `workflowId` property must be unique across all workflows +- [sourceDescriptions-not-empty](./arazzo/sourceDescriptions-not-empty.md): the `sourceDescriptions` must be defined and the list must have at least one entry. -- Verbose syntax, where you can configure additional options for rules that support them. +### Spot -```yaml -apis: - main: - root: ./openapi/openapi.yaml - rules: - specific-api-rule: - severity: warn -rules: - example-rule-name: - severity: error - rule-option-one: value - rule-option-two: value -``` +- [no-actions-type-end](./spot/no-actions-type-end.test.md): the `end` type action is not supported by Spot. +- [no-criteria-xpath](./spot/no-criteria-xpath.md): the `xpath` type criteria is not supported by Spot. +- [parameters-not-in-body](./spot/parameters-not-in-body.md): the `in` section inside `parameters` must not contain a `body`. +- [version-enum](./spot/version-enum.md): the `version` property must be one of the supported values. -## Next steps +## Resources - Learn more about [API linting](../api-standards.md), or follow the [guide to configuring a ruleset](../guides/configure-rules.md). +- Visit the [documentation on per-API configuration](../configuration/apis.md) - If you didn't find the rule you need, build a [configurable rule](./configurable-rules.md) for a perfect linting fit. diff --git a/docs/rules/configure-rules.md b/docs/rules/configure-rules.md new file mode 100644 index 000000000..c60e8466b --- /dev/null +++ b/docs/rules/configure-rules.md @@ -0,0 +1,61 @@ +# Configure linting rules + +Configure the rules for API linting in the `redocly.yaml` configuration file. + +You can add rules, change their severity, or turn them off completely. +Some rules support additional configuration. + +You can also provide per-format or even per-API rule configuration. +Use these approaches when your different types of API, or individual APIs, have different linting requirements. + +## Simple rule configuration + +The following example shows rules configured in `redocly.yaml` with short syntax using the format `rule-name: {severity}`, where `{severity}` is one of `error`, `warn` or `off`: + +```yaml +rules: + operation-operationId: warn + +``` + +Some rules support additional configuration options. The following example shows the more verbose format where the `severity` setting is added alongside other settings: + +```yaml +rules: + path-excludes-patterns: + severity: error + patterns: + - ^\/fetch + - ^\/v[0-9] +``` + +Check the documentation for each rule to see if it supports additional configuration. + +## Per-API configuration + +You can set different rules for different APIs by adding a `rules` object under each API in `apis`. + +```yaml +rules: + operation-operationId: error + +apis: + museum: + root: ./apis/museum.yaml + rules: + info-license: warn + tickets@beta: + root: ./apis/tickets.yaml + rules: + info-license: error + operation-operationId-url-safe: error + operation-operationId-unique: error + +``` + +Each API picks up the settings that relate to it and gets linted accordingly. + +## Resources + +- Learn more about [rules and rulesets](../rules.md). +- Check the list of [built-in rules](./built-in-rules.md). diff --git a/docs/rules/minimal.md b/docs/rules/minimal.md index bbc49fddb..6a651a60a 100644 --- a/docs/rules/minimal.md +++ b/docs/rules/minimal.md @@ -1,7 +1,3 @@ ---- -slug: /docs/cli/rules/minimal ---- - # Minimal ruleset The rules contained in the minimal ruleset: @@ -12,6 +8,8 @@ Errors: - [no-server-variables-empty-enum](./no-server-variables-empty-enum.md) - [no-unresolved-refs](./no-unresolved-refs.md) - [spec](./spec.md) +- [stepId-unique](./arazzo/stepId-unique.md) +- [workflowId-unique](./arazzo/workflowId-unique.md) Warnings: @@ -38,3 +36,6 @@ Warnings: - [security-defined](./security-defined.md) - [spec-components-invalid-map-name](./spec-components-invalid-map-name.md) - [tag-description](./tag-description.md) +- [version-enum](./spot/version-enum.md) + +A copy/pastable version of this ruleset is available as a [ruleset template](./ruleset-templates.md). diff --git a/docs/rules/recommended.md b/docs/rules/recommended.md index 8869d0ecb..2e5d51e88 100644 --- a/docs/rules/recommended.md +++ b/docs/rules/recommended.md @@ -1,7 +1,3 @@ ---- -slug: /docs/cli/rules/recommended ---- - # Recommended ruleset These are the rules in the `recommended` set, grouped by their severity. @@ -27,6 +23,12 @@ Errors: - [security-defined](./security-defined.md) - [spec-components-invalid-map-name](./spec-components-invalid-map-name.md) - [spec](./spec.md) +- [parameters-unique](./arazzo/parameters-unique.md) +- [sourceDescription-type](./arazzo/sourceDescriptions-type.md) +- [sourceDescription-name-unique](./arazzo/sourceDescriptions-name-unique.md) +- [stepId-unique](./arazzo/stepId-unique.md) +- [workflow-dependsOn](./arazzo/workflow-dependsOn.md) +- [workflowId-unique](./arazzo/workflowId-unique.md) Warnings: @@ -41,7 +43,16 @@ Warnings: - [operation-4xx-response](./operation-4xx-response.md) - [operation-operationId](./operation-operationId.md) - [tag-description](./tag-description.md) +- [version-enum](./spot/version-enum.md) +- [parameters-not-in-body](./spot/parameters-not-in-body.md) +- [requestBody-replacements-unique](./arazzo/requestBody-replacements-unique.md) +- [step-onFailure-unique](./arazzo/step-onFailure-unique.md) +- [step-onSuccess-unique](./arazzo/step-onSuccess-unique.md) ## Recommended strict ruleset There is also a `recommended-strict` version of `recommended`, which elevates all warnings to errors. + +## Ruleset template + +A copy/pastable version of this ruleset is available as a [ruleset template](./ruleset-templates.md). diff --git a/docs/rules/required-string-property-missing-min-length.md b/docs/rules/required-string-property-missing-min-length.md index 531eb284f..f539d37e2 100644 --- a/docs/rules/required-string-property-missing-min-length.md +++ b/docs/rules/required-string-property-missing-min-length.md @@ -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](/docs/cli/rules.md#severity-settings) for the rule. +Set the desired [severity](../rules.md#severity-settings) for the rule. ```yaml rules: diff --git a/docs/rules/ruleset-templates.md b/docs/rules/ruleset-templates.md new file mode 100644 index 000000000..ab274b9f8 --- /dev/null +++ b/docs/rules/ruleset-templates.md @@ -0,0 +1,515 @@ +# Ruleset templates + +Redocly CLI includes some default rulesets to get you started quickly. + +To edit/adjust the rules you use in your own projects, [configure your rules](./configure-rules.md) accordingly to override any settings from the original ruleset. + +On this page, each ruleset is included for each of the supported API description formats. +You can use this information for your own reference, or copy/paste them in order to use [separate configuration for each API](../configuration/apis.md). +Consult the format-specific sections below, each code sample is formatted to be included in `redocly.yaml` directly. + +More information and examples for individual rules can be found in the [built-in rules documentation](./built-in-rules.md). + +## Minimal rulesets + +The minimal rulesets are a decent baseline that you can use to selective enable more rules or extend rulesets from. + +### Minimal ruleset: OpenAPI 3.1 + +```yaml +rules: + 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 + 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 + 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 + 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 + no-invalid-media-type-examples: warn + no-server-example.com: warn + no-server-trailing-slash: error + no-empty-servers: warn + no-example-value-and-externalValue: warn + 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-4xx-problem-details-rfc7807: off + request-mime-type: off + response-contains-property: off + response-mime-type: off + array-parameter-serialization: off +``` + +### Minimal ruleset: OpenAPI 3.0 + +```yaml +rules: + 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 + 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 + 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 + 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 + no-invalid-media-type-examples: warn + no-server-example.com: warn + no-server-trailing-slash: error + no-empty-servers: warn + no-example-value-and-externalValue: warn + 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-4xx-problem-details-rfc7807: off + request-mime-type: off + response-contains-property: off + response-mime-type: off + array-parameter-serialization: off +``` + +### Minimal ruleset: OpenAPI 2.0 + +```yaml +rules: + 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 + 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 + 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 + 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 + boolean-parameter-prefixes: off + request-mime-type: off + response-contains-property: off + response-mime-type: off +``` + +### Minimal ruleset: AsyncAPI 3.0 + +```yaml +rules: + spec: error + info-contact: off + info-license-strict: off + operation-operationId: warn + tag-description: warn + tags-alphabetical: off + channels-kebab-case: off + no-channel-trailing-slash: off +``` + +### Minimal ruleset: AsyncAPI 2.6 + +```yaml +rules: + spec: error + info-contact: off + info-license-strict: off + operation-operationId: warn + tag-description: warn + tags-alphabetical: off + channels-kebab-case: off + no-channel-trailing-slash: off +``` + +### Minimal ruleset: Arazzo 1.0 + +```yaml +rules: + spec: error + parameters-not-in-body: off + sourceDescription-type: off + version-enum: warn + workflowId-unique: error + stepId-unique: error + sourceDescription-name-unique: off + 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 +``` + +## Recommended rulesets + +The default behavior is to use a recommended ruleset. +The recommended rulesets for each format are listed below. +There is also a "recommended-strict" ruleset which is identical but with all `warn` settings changed to `error`. + +### Recommended ruleset: OpenAPI 3.1 + +```yaml +rules: + 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 + 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-parameters-unique: error + operation-tag-defined: off + security-defined: error + operation-singular-tag: off + no-unresolved-refs: error + no-enum-type-mismatch: 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 + +oas3_1Rules: + 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 + 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-parameters-unique: error + operation-tag-defined: off + security-defined: error + operation-singular-tag: off + no-unresolved-refs: error + no-enum-type-mismatch: 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 + no-invalid-media-type-examples: warn + no-server-example.com: warn + no-server-trailing-slash: error + no-empty-servers: error + no-example-value-and-externalValue: error + 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-4xx-problem-details-rfc7807: off + request-mime-type: off + response-contains-property: off + response-mime-type: off + array-parameter-serialization: off +``` + +### Recommended ruleset: OpenAPI 3.0 + +```yaml +rules: + 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 + 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-parameters-unique: error + operation-tag-defined: off + security-defined: error + operation-singular-tag: off + no-unresolved-refs: error + no-enum-type-mismatch: 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 + no-invalid-media-type-examples: warn + no-server-example.com: warn + no-server-trailing-slash: error + no-empty-servers: error + no-example-value-and-externalValue: error + 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-4xx-problem-details-rfc7807: off + request-mime-type: off + response-contains-property: off + response-mime-type: off + array-parameter-serialization: off +``` + +### Recommended ruleset: OpenAPI 2.0 + +```yaml +rules: + 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 + 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-parameters-unique: error + operation-tag-defined: off + security-defined: error + operation-singular-tag: off + no-unresolved-refs: error + no-enum-type-mismatch: 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 + boolean-parameter-prefixes: off + request-mime-type: off + response-contains-property: off + response-mime-type: off +``` + +### Recommended ruleset: AsyncAPI 3.0 + +```yaml +rules: + spec: error + info-contact: off + info-license-strict: warn + operation-operationId: warn + tag-description: warn + tags-alphabetical: off + channels-kebab-case: off + no-channel-trailing-slash: off +``` + +### Recommended ruleset: AsyncAPI 2.6 + +```yaml +rules: + spec: error + info-contact: off + info-license-strict: warn + operation-operationId: warn + tag-description: warn + tags-alphabetical: off + channels-kebab-case: off + no-channel-trailing-slash: off +``` + +### Recommended ruleset: Arazzo 1.0 + +```yaml +rules: + spec: error + parameters-not-in-body: warn + sourceDescription-type: error + version-enum: warn + workflowId-unique: error + stepId-unique: error + sourceDescription-name-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 +``` + +## Resources + +- Learn about [API governance](../api-standards.md). +- More information and examples for individual rules can be found in the [built-in rules documentation](./built-in-rules.md). +- Add your own [configurable rules](./configurable-rules.md) if there's anything you need that isn't already provided as a built in rule. diff --git a/docs/rules/scalar-property-missing-example.md b/docs/rules/scalar-property-missing-example.md index 4fdbc1730..561391f63 100644 --- a/docs/rules/scalar-property-missing-example.md +++ b/docs/rules/scalar-property-missing-example.md @@ -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](/docs/cli/rules.md#severity-settings) for the rule. +Set the desired [severity](../rules.md#severity-settings) for the rule. ```yaml rules: diff --git a/docs/rules/spec-strict-refs.md b/docs/rules/spec-strict-refs.md index 790e8fcbc..2fc28288c 100644 --- a/docs/rules/spec-strict-refs.md +++ b/docs/rules/spec-strict-refs.md @@ -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](/docs/cli/rules.md#severity-settings). +set the desired [severity](../rules.md#severity-settings). | Option | Type | Description | | -------- | ------ | ---------------------------------------------------------------------------------------- | diff --git a/docs/rules/spec.md b/docs/rules/spec.md index c7e2d9697..440bae0fe 100644 --- a/docs/rules/spec.md +++ b/docs/rules/spec.md @@ -1,7 +1,3 @@ ---- -slug: /docs/cli/rules/spec ---- - # spec Ensures that your API document conforms to the [OpenAPI specification](https://spec.openapis.org/oas/v3.1.0.html). @@ -12,6 +8,15 @@ Ensures that your API document conforms to the [OpenAPI specification](https://s | 3.0 | ✅ | | 3.1 | ✅ | +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +| AsyncAPI | Compatibility | +| -------- | ------------- | +| 2.0 | ✅ | +| 3.0 | ✅ | + The default setting for this rule (in the `recommended` and `minimal` configuration) is `error`. This is an essential rule that should not be turned off except in rare and special cases. diff --git a/docs/rules/spot/parameters-not-in-body.md b/docs/rules/spot/parameters-not-in-body.md new file mode 100644 index 000000000..b045c6b5f --- /dev/null +++ b/docs/rules/spot/parameters-not-in-body.md @@ -0,0 +1,69 @@ +# parameters-not-in-body + +Requires the `in` section inside `parameters` must not contain a `body`. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## API design principles + +This is rule is specific to the Spot tool. +`body` is not supported in the `in` section inside `parameters`. +This affects parameter lists in: + +- `workflows.[workflow].parameters` +- `workflows.[workflow[.steps.[step].parameters` +- `x-parameters` + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +arazzoRules: + parameters-not-in-body: error +``` + +## Examples + +Given the following configuration: + +```yaml +arazzoRules: + parameters-not-in-body: error +``` + +Example of an **incorrect** list of `parameters`: + +```yaml Object example +workflows: + - workflowId: get-museum-hours + parameters: + - in: body + name: Authorization + value: Basic Og== +``` + +Example of a **correct** list of `parameters`: + +```yaml Object example +workflows: + - workflowId: get-museum-hours + parameters: + - in: header + name: Authorization + value: Basic Og== +``` + +## Related rules + +- [version-enum](./version-enum.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/spot/parameters-not-in-body.ts) diff --git a/docs/rules/spot/version-enum.md b/docs/rules/spot/version-enum.md new file mode 100644 index 000000000..fac20d762 --- /dev/null +++ b/docs/rules/spot/version-enum.md @@ -0,0 +1,54 @@ +# version-enum + +Requires the `version` property must be one of the supported values. + +| Arazzo | Compatibility | +| ------ | ------------- | +| 1.0.0 | ✅ | + +## API design principles + +This rule is used with Spot. +The `version` property must be one of the Spot-supported values which may be different to the latest `Arazzo` version. + +## Configuration + +| Option | Type | Description | +| -------- | ------ | ------------------------------------------------------- | +| severity | string | Possible values: `off`, `warn`, `error`. Default `off`. | + +An example configuration: + +```yaml +arazzoRules: + version-enum: error +``` + +## Examples + +Given the following configuration: + +```yaml +arazzoRules: + version-enum: error +``` + +Example of an **incorrect** entry: + +```yaml Object example +arazzo: 4.2.0 +``` + +Example of a **correct** entry: + +```yaml Object example +arazzo: 1.0.0 +``` + +## Related rules + +- [parameters-not-in-body](./parameters-not-in-body.md) + +## Resources + +- [Rule source](https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/spot/version-enum.ts) diff --git a/docs/rules/tag-description.md b/docs/rules/tag-description.md index c5bbe80c6..33586d774 100644 --- a/docs/rules/tag-description.md +++ b/docs/rules/tag-description.md @@ -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](/docs/cli/rules.md#severity-settings) for the rule. +Set the desired [severity](../rules.md#severity-settings) for the rule. ```yaml rules: diff --git a/docs/sidebars.yaml b/docs/sidebars.yaml index 6fd99ac47..0af379e24 100644 --- a/docs/sidebars.yaml +++ b/docs/sidebars.yaml @@ -71,10 +71,16 @@ page: api-standards.md items: - page: rules.md - label: Rules + group: Rules and rulesets + items: + - page: rules/recommended.md + - page: rules/minimal.md + - page: rules/ruleset-templates.md - group: Built-in rules page: rules/built-in-rules.md items: + - separator: OpenAPI + - page: rules/array-parameter-serialization.md - page: rules/boolean-parameter-prefixes.md - page: rules/component-name-unique.md - page: rules/info-contact.md @@ -127,6 +133,27 @@ - page: rules/spec-strict-refs.md - page: rules/tag-description.md - page: rules/tags-alphabetical.md + - separator: AsyncAPI + - page: rules/async/channels-kebab-case.md + - page: rules/async/no-channel-trailing-slash.md + - separator: Arazzo + - page: rules/spot/no-actions-type-end.test.md + - page: rules/spot/no-criteria-xpath.md + - page: rules/spot/parameters-not-in-body.md + - page: rules/spot/version-enum.md + - page: rules/arazzo/criteria-unique.md + - page: rules/arazzo/parameters-unique.md + - page: rules/arazzo/requestBody-replacements-unique.md + - page: rules/arazzo/sourceDescriptions-name-unique.md + - page: rules/arazzo/sourceDescriptions-type.md + - page: rules/arazzo/stepId-unique.md + - page: rules/arazzo/step-onFailure-unique.md + - page: rules/arazzo/step-onSuccess-unique.md + - page: rules/arazzo/workflow-dependsOn.md + - page: rules/arazzo/workflowId-unique.md + + - page: rules/configure-rules.md + label: Rule configuration - page: rules/configurable-rules.md - group: Decorators page: decorators.md diff --git a/packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts b/packages/core/src/rules/arazzo/__tests__/sourceDescription-type.test.ts similarity index 100% rename from packages/core/src/rules/arazzo/__tests__/source-description-type.test.ts rename to packages/core/src/rules/arazzo/__tests__/sourceDescription-type.test.ts diff --git a/packages/core/src/rules/arazzo/index.ts b/packages/core/src/rules/arazzo/index.ts index c00261a2f..06981d49c 100644 --- a/packages/core/src/rules/arazzo/index.ts +++ b/packages/core/src/rules/arazzo/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../common/spec'; import { Assertions } from '../common/assertions'; import { ParametersNotInBody } from '../spot/parameters-not-in-body'; -import { SourceDescriptionType } from '../arazzo/source-description-type'; +import { SourceDescriptionsType } from './sourceDescriptions-type'; import { VersionEnum } from '../spot/version-enum'; import { WorkflowIdUnique } from './workflowId-unique'; import { StepIdUnique } from './stepId-unique'; @@ -22,7 +22,7 @@ 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, + 'sourceDescription-type': SourceDescriptionsType as ArazzoRule, 'version-enum': VersionEnum as ArazzoRule, 'workflowId-unique': WorkflowIdUnique as ArazzoRule, 'stepId-unique': StepIdUnique as ArazzoRule, diff --git a/packages/core/src/rules/arazzo/source-description-type.ts b/packages/core/src/rules/arazzo/sourceDescriptions-type.ts similarity index 91% rename from packages/core/src/rules/arazzo/source-description-type.ts rename to packages/core/src/rules/arazzo/sourceDescriptions-type.ts index efc433139..e5cd61916 100644 --- a/packages/core/src/rules/arazzo/source-description-type.ts +++ b/packages/core/src/rules/arazzo/sourceDescriptions-type.ts @@ -1,7 +1,7 @@ import type { ArazzoRule } from '../../visitors'; import type { UserContext } from '../../walk'; -export const SourceDescriptionType: ArazzoRule = () => { +export const SourceDescriptionsType: ArazzoRule = () => { return { SourceDescriptions: { enter(SourceDescriptions, { report, location }: UserContext) {