Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into asyncapi/message-e…
Browse files Browse the repository at this point in the history
…xamples
  • Loading branch information
P0lip committed Jun 6, 2022
2 parents 0afcf21 + 1f1fd92 commit 038b53c
Show file tree
Hide file tree
Showing 38 changed files with 1,313 additions and 18 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ If you have a bug or feature request, please [create an issue](https://github.co

### How is this different to Ajv

[Ajv](https://www.npmjs.com/package/ajv) is a JSON Schema validator, and Spectral is a JSON/YAML linter. Instead of just validating against JSON Schema, it can be used to write rules for any sort of JSON/YAML object, which could be JSON Schema, or OpenAPI, or anything similar. Spectral does expose a [`schema` function](https://meta.stoplight.io/docs/spectral/docs/reference/functions.md) that you can use in your rules to validate all or part of the target object with JSON Schema (we even use Ajv used under the hood for this), but that's just one of many functions.
[Ajv](https://www.npmjs.com/package/ajv) is a JSON Schema validator, and Spectral is a JSON/YAML linter. Instead of just validating against JSON Schema, it can be used to write rules for any sort of JSON/YAML object, which could be JSON Schema, or OpenAPI, or anything similar. Spectral does expose a [`schema` function](https://meta.stoplight.io/docs/spectral/docs/reference/functions.md) that you can use in your rules to validate all or part of the target object with JSON Schema (we even use Ajv under the hood for this), but that's just one of many functions.

### I want to lint my OpenAPI documents but don't want to implement Spectral right now.

Expand All @@ -91,9 +91,10 @@ No problem! A hosted version of Spectral comes **free** with the Stoplight platf

## ⚙️ Integrations

- [Stoplight Studio](https://stoplight.io/studio?utm_source=github&utm_medium=spectral&utm_campaign=readme) uses Spectral to validate and lint OpenAPI documents.
- [Spectral GitHub Action](https://github.com/stoplightio/spectral-action), lints documents in your repo, built by [Vincenzo Chianese](https://github.com/XVincentX/).
- [VS Code Spectral](https://github.com/stoplightio/vscode-spectral), all the power of Spectral without leaving VS Code.
- [GitHub Action](https://github.com/stoplightio/spectral-action) - lints documents in your repo, built by [Vincenzo Chianese](https://github.com/XVincentX/).
- [Jetbrains Plugin](https://plugins.jetbrains.com/plugin/18520-spectral), Automatic linting of your OpenAPI specifications and highlighting in your editor.
- [Stoplight Studio](https://stoplight.io/studio?utm_source=github&utm_medium=spectral&utm_campaign=readme) - Uses Spectral to validate and lint OpenAPI documents.
- [VS Code Spectral](https://marketplace.visualstudio.com/items?itemName=stoplight.spectral), all the power of Spectral without leaving VS Code.

## 🏁 Help Others Utilize Spectral

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/4-custom-rulesets.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ where you may need to run a rule on the "raw" un-resolved document.

For example, if you want to enforce conventions on the folder structure used for
[splitting up
documents](https://stoplight.io/blog/keeping-openapi-dry-and-portable/?utm_source=github&utm_medium=spectral&utm_campaign=docs).
documents](https://blog.stoplight.io/keeping-openapi-dry-and-portable?utm_medium=spectral&utm_source=github&utm_campaign=docs).

If your rule needs to access the raw `$ref` reference values, you can set
`resolved: false` to allow the rule to receive the raw un-resolved version of
Expand Down
64 changes: 64 additions & 0 deletions docs/reference/asyncapi-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Keep trailing slashes off of channel names, as it can cause some confusion. Most

**Recommended:** Yes

### asyncapi-channel-parameters

All channel parameters should be defined in the `parameters` object of the channel. They should also not contain redundant parameters that do not exist in the channel address.

**Recommended:** Yes

### asyncapi-headers-schema-type-object

The schema definition of the application headers must be of type “object”.
Expand Down Expand Up @@ -177,6 +183,36 @@ Operation objects should have a description.

**Recommended:** Yes

### asyncapi-operation-operationId-uniqueness

`operationId` must be unique across all the operations (except these one defined in the components).

**Recommended:** Yes

**Bad Example**

```yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
operationId: turn
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
operationId: turn
```

**Good Example**

```yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
operationId: turnOn
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
operationId: turnOff
```

### asyncapi-operation-operationId

This operation ID is essentially a reference for the operation. Tools may use it for defining function names, class method names, and even URL hashes in documentation systems.
Expand Down Expand Up @@ -333,6 +369,12 @@ Server URL should not point at example.com.

**Recommended:** No

### asyncapi-server-variables

All server URL variables should be defined in the `variables` object of the server. They should also not contain redundant variables that do not exist in the server address.

**Recommended:** Yes

### asyncapi-servers

A non empty `servers` object is expected to be located at the root of the document.
Expand Down Expand Up @@ -386,6 +428,28 @@ tags:

**Recommended:** No

### asyncapi-tags-uniqueness

Tags must not have duplicate names (identifiers).

**Recommended:** Yes

**Bad Example**

```yaml
tags:
- name: "Badger"
- name: "Badger"
```

**Good Example**

```yaml
tags:
- name: "Aardvark"
- name: "Badger"
```

### asyncapi-tags

AsyncAPI object should have non-empty `tags` array.
Expand Down
22 changes: 22 additions & 0 deletions docs/reference/openapi-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,28 @@ tags:
- name: "Badger"
```

### openapi-tags-uniqueness

OpenAPI object must not have duplicated tag names (identifiers).

**Recommended:** Yes

**Bad Example**

```yaml
tags:
- name: "Badger"
- name: "Badger"
```

**Good Example**

```yaml
tags:
- name: "Aardvark"
- name: "Badger"
```

### openapi-tags

OpenAPI object should have non-empty `tags` array.
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [@stoplight/spectral-cli-v6.4.1](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-cli-v6.4.0...@stoplight/spectral-cli-v6.4.1) (2022-06-01)


### Bug Fixes

* **cli:** do not show 'or higher' if severity equals error ([#2172](https://github.com/stoplightio/spectral/issues/2172)) ([f31ec63](https://github.com/stoplightio/spectral/commit/f31ec636c912f3c9a53672e87a13ad724921b902))

# [@stoplight/spectral-cli-v6.4.0](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-cli-v6.3.0...@stoplight/spectral-cli-v6.4.0) (2022-05-12)


Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/spectral-cli",
"version": "6.4.0",
"version": "6.4.1",
"homepage": "https://github.com/stoplightio/spectral",
"bugs": "https://github.com/stoplightio/spectral/issues",
"author": "Stoplight <[email protected]>",
Expand Down
9 changes: 6 additions & 3 deletions packages/cli/src/commands/lint.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Dictionary } from '@stoplight/types';
import { DiagnosticSeverity, Dictionary } from '@stoplight/types';
import { isPlainObject } from '@stoplight/json';
import { getDiagnosticSeverity, IRuleResult } from '@stoplight/spectral-core';
import { isError, difference, pick } from 'lodash';
import { difference, isError, pick } from 'lodash';
import type { ReadStream } from 'tty';
import type { CommandModule } from 'yargs';
import * as process from 'process';
Expand Down Expand Up @@ -207,7 +207,10 @@ const lintCommand: CommandModule = {
if (results.length > 0) {
process.exit(severeEnoughToFail(results, failSeverity) ? 1 : 0);
} else if (config.quiet !== true) {
process.stdout.write(`No results with a severity of '${failSeverity}' or higher found!`);
const isErrorSeverity = getDiagnosticSeverity(failSeverity) === DiagnosticSeverity.Error;
process.stdout.write(
`No results with a severity of '${failSeverity}' ${isErrorSeverity ? '' : 'or higher '}found!`,
);
}
} catch (ex) {
fail(isError(ex) ? ex : new Error(String(ex)), config.verbose === true);
Expand Down
9 changes: 9 additions & 0 deletions packages/rulesets/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# [@stoplight/spectral-rulesets-v1.9.0](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-rulesets-v1.8.0...@stoplight/spectral-rulesets-v1.9.0) (2022-05-31)


### Features

* **rulesets:** add rules for validation of server variables and channel parameters ([#2101](https://github.com/stoplightio/spectral/issues/2101)) ([9acc633](https://github.com/stoplightio/spectral/commit/9acc63375309bd7babe8b0130bd64fbbdbc56738))
* **rulesets:** add rules for validation uniqueness of tag names ([#2104](https://github.com/stoplightio/spectral/issues/2104)) ([4447d81](https://github.com/stoplightio/spectral/commit/4447d81ace5aab90e7cd48a8e182103b6a90ee81))
* **rulesets:** check uniqueness of AsyncAPI operations ([#2121](https://github.com/stoplightio/spectral/issues/2121)) ([8b3cce4](https://github.com/stoplightio/spectral/commit/8b3cce4bc054df7843e50312eae225ca8a7a50b0))

# [@stoplight/spectral-rulesets-v1.8.0](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-rulesets-v1.7.0...@stoplight/spectral-rulesets-v1.8.0) (2022-05-03)


Expand Down
2 changes: 1 addition & 1 deletion packages/rulesets/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/spectral-rulesets",
"version": "1.8.0",
"version": "1.9.0",
"homepage": "https://github.com/stoplightio/spectral",
"bugs": "https://github.com/stoplightio/spectral/issues",
"author": "Stoplight <[email protected]>",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/tester';

testRule('asyncapi-channel-parameters', [
{
name: 'valid case',
document: {
asyncapi: '2.0.0',
channels: {
'users/{userId}/signedUp': {
parameters: {
userId: {},
},
},
},
},
errors: [],
},

{
name: 'channel has not defined definition for one of the parameters',
document: {
asyncapi: '2.0.0',
channels: {
'users/{userId}/{anotherParam}/signedUp': {
parameters: {
userId: {},
},
},
},
},
errors: [
{
message: 'Not all channel\'s parameters are described with "parameters" object. Missed: anotherParam.',
path: ['channels', 'users/{userId}/{anotherParam}/signedUp', 'parameters'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'channel has not defined definition for two+ of the parameters',
document: {
asyncapi: '2.0.0',
channels: {
'users/{userId}/{anotherParam1}/{anotherParam2}/signedUp': {
parameters: {
userId: {},
},
},
},
},
errors: [
{
message:
'Not all channel\'s parameters are described with "parameters" object. Missed: anotherParam1, anotherParam2.',
path: ['channels', 'users/{userId}/{anotherParam1}/{anotherParam2}/signedUp', 'parameters'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'channel has not defined definition for one of the parameters (in the components.channels)',
document: {
asyncapi: '2.3.0',
components: {
channels: {
'users/{userId}/{anotherParam}/signedUp': {
parameters: {
userId: {},
},
},
},
},
},
errors: [
{
message: 'Not all channel\'s parameters are described with "parameters" object. Missed: anotherParam.',
path: ['components', 'channels', 'users/{userId}/{anotherParam}/signedUp', 'parameters'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'channel has redundant paramaters',
document: {
asyncapi: '2.0.0',
channels: {
'users/{userId}/signedUp': {
parameters: {
userId: {},
anotherParam1: {},
anotherParam2: {},
},
},
},
},
errors: [
{
message: 'Channel\'s "parameters" object has redundant defined "anotherParam1" parameter.',
path: ['channels', 'users/{userId}/signedUp', 'parameters', 'anotherParam1'],
severity: DiagnosticSeverity.Error,
},
{
message: 'Channel\'s "parameters" object has redundant defined "anotherParam2" parameter.',
path: ['channels', 'users/{userId}/signedUp', 'parameters', 'anotherParam2'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'channel has redundant paramaters (in the components.channels)',
document: {
asyncapi: '2.3.0',
components: {
channels: {
'users/{userId}/signedUp': {
parameters: {
userId: {},
anotherParam1: {},
anotherParam2: {},
},
},
},
},
},
errors: [
{
message: 'Channel\'s "parameters" object has redundant defined "anotherParam1" parameter.',
path: ['components', 'channels', 'users/{userId}/signedUp', 'parameters', 'anotherParam1'],
severity: DiagnosticSeverity.Error,
},
{
message: 'Channel\'s "parameters" object has redundant defined "anotherParam2" parameter.',
path: ['components', 'channels', 'users/{userId}/signedUp', 'parameters', 'anotherParam2'],
severity: DiagnosticSeverity.Error,
},
],
},
]);
Loading

0 comments on commit 038b53c

Please sign in to comment.