Repository: stoplightio/spectral
Pull request #2618 (2024-05-03 13:07:04)

docs(rulesets): update asyncapi ruleset link
**Checklist**

- [ ] Tests added / updated
- [X] Docs added / updated

**Does this PR introduce a breaking change?**

- [ ] Yes
- [X] No


**Screenshots**

**Before**:
![image](https://github.com/RafaelJCamara/spectral/assets/52082556/e3a7ee80-f69f-443e-b2f6-8292f41f255e)

**After**:
![image](https://github.com/RafaelJCamara/spectral/assets/52082556/80904610-ba9e-4fc7-ae40-299a53a7f1fb)


**Additional context**

When you go to the AsyncAPI rules, there's a link for the supported AsyncAPI specification version:
![image](https://github.com/RafaelJCamara/spectral/assets/52082556/7bf26eda-7888-449d-9485-271193dc23fd)

When you click the existing link, we get the 404 mentioned in the above screenshot.

With this PR, we get a new non-broken link.



Patch:
diff --git a/docs/reference/asyncapi-rules.md b/docs/reference/asyncapi-rules.md
index 091f319a..a8056fc6 100644
--- a/docs/reference/asyncapi-rules.md
+++ b/docs/reference/asyncapi-rules.md
@@ -1,6 +1,6 @@
 # AsyncAPI Rules
 
-Spectral has a built-in "asyncapi" ruleset for the [AsyncAPI Specification](https://www.asyncapi.com/docs/specifications/v2.0.0).
+Spectral has a built-in "asyncapi" ruleset for the [AsyncAPI Specification](https://v2.asyncapi.com/docs/reference).
 
 In your ruleset file you can add `extends: "spectral:asyncapi"` and you'll get all of the following rules applied.
 
diff --git a/docs/reference/openapi-rules.md b/docs/reference/openapi-rules.md
index 0ea70cde..56b06601 100644
--- a/docs/reference/openapi-rules.md
+++ b/docs/reference/openapi-rules.md
@@ -920,3 +920,66 @@ servers:
 ```
 
 In this example, both **`{region}`** and **`{version}`** variables are properly defined and used in the server URL. Also, the default value for **`region`** is within the allowed values.
+
+### oas3_callbacks_in_callbacks
+
+A callback should not be defined within another callback.
+
+**Recommended:** Yes
+
+**Bad Example**
+
+```yaml
+paths:
+  /path:
+    get:
+      callbacks:
+        onData:
+          /data:
+            post:
+              callbacks: ...
+```
+
+### oas3_1-servers-in-webhook
+
+Servers should not be defined in a webhook.
+
+**Recommended:** Yes
+
+**Bad Example**
+
+At the path item object level:
+
+```yaml
+webhooks:
+  servers:
+    - url: https://example.com/
+    - url: https://example.com/api/
+```
+
+or
+
+At the operation level:
+
+```yaml
+webhooks:
+  newPet:
+    post:
+      servers:
+        -url: https://example.com/
+```
+
+### oas3_1-callbacks-in-webhook
+
+Callbacks should not be defined in a webhook.
+
+**Recommended:** Yes
+
+**Bad Example**
+
+```yaml
+webhooks:
+  newPet:
+    post:
+      callbacks: ...
+```
diff --git a/packages/rulesets/src/oas/index.ts b/packages/rulesets/src/oas/index.ts
index f6f0e051..67af689d 100644
--- a/packages/rulesets/src/oas/index.ts
+++ b/packages/rulesets/src/oas/index.ts
@@ -707,5 +707,32 @@ const ruleset = {
         },
       },
     },
+    'oas3-callbacks-in-callbacks': {
+      message: 'Callbacks should not be defined within a callback',
+      formats: [oas3],
+      recommended: true,
+      given: ['#OperationObject.callbacks[*][*][*].callbacks'],
+      then: {
+        function: undefined,
+      },
+    },
+    'oas3_1-servers-in-webhook': {
+      message: 'Servers should not be defined in a webhook.',
+      formats: [oas3_1],
+      recommended: true,
+      given: ['$.webhooks.servers', '$.webhooks[*][*].servers'],
+      then: {
+        function: undefined,
+      },
+    },
+    'oas3_1-callbacks-in-webhook': {
+      message: 'Callbacks should not be defined in a webhook.',
+      formats: [oas3_1],
+      recommended: true,
+      given: ['$.webhooks[*][*].callbacks'],
+      then: {
+        function: undefined,
+      },
+    },
   },
 };


Test patch:
diff --git a/packages/rulesets/src/oas/__tests__/oas3-callbacks-in-callbacks.test.ts b/packages/rulesets/src/oas/__tests__/oas3-callbacks-in-callbacks.test.ts
new file mode 100644
index 00000000..6c3a5413
--- /dev/null
+++ b/packages/rulesets/src/oas/__tests__/oas3-callbacks-in-callbacks.test.ts
@@ -0,0 +1,33 @@
+import { DiagnosticSeverity } from '@stoplight/types';
+import testRule from '../../__tests__/__helpers__/tester';
+
+testRule('oas3-callbacks-in-callbacks', [
+  {
+    name: 'callbacks defined within a callback',
+    document: {
+      openapi: '3.0.0',
+      paths: {
+        '/path': {
+          get: {
+            callbacks: {
+              onData: {
+                '/data': {
+                  post: {
+                    callbacks: {},
+                  },
+                },
+              },
+            },
+          },
+        },
+      },
+    },
+    errors: [
+      {
+        message: 'Callbacks should not be defined within a callback',
+        path: ['paths', '/path', 'get', 'callbacks', 'onData', '/data', 'post', 'callbacks'],
+        severity: DiagnosticSeverity.Warning,
+      },
+    ],
+  },
+]);
diff --git a/packages/rulesets/src/oas/__tests__/oas3_1-callbacks-in-webhook.test.ts b/packages/rulesets/src/oas/__tests__/oas3_1-callbacks-in-webhook.test.ts
new file mode 100644
index 00000000..0706cdf6
--- /dev/null
+++ b/packages/rulesets/src/oas/__tests__/oas3_1-callbacks-in-webhook.test.ts
@@ -0,0 +1,25 @@
+import { DiagnosticSeverity } from '@stoplight/types';
+import testRule from '../../__tests__/__helpers__/tester';
+
+testRule('oas3_1-callbacks-in-webhook', [
+  {
+    name: 'callbacks defined in webhook',
+    document: {
+      openapi: '3.1.0',
+      webhooks: {
+        newPet: {
+          post: {
+            callbacks: {},
+          },
+        },
+      },
+    },
+    errors: [
+      {
+        message: 'Callbacks should not be defined in a webhook.',
+        path: ['webhooks', 'newPet', 'post', 'callbacks'],
+        severity: DiagnosticSeverity.Warning,
+      },
+    ],
+  },
+]);
diff --git a/packages/rulesets/src/oas/__tests__/oas3_1-servers-in-webhook.test.ts b/packages/rulesets/src/oas/__tests__/oas3_1-servers-in-webhook.test.ts
new file mode 100644
index 00000000..3e2ebe43
--- /dev/null
+++ b/packages/rulesets/src/oas/__tests__/oas3_1-servers-in-webhook.test.ts
@@ -0,0 +1,31 @@
+import { DiagnosticSeverity } from '@stoplight/types';
+import testRule from '../../__tests__/__helpers__/tester';
+
+testRule('oas3_1-servers-in-webhook', [
+  {
+    name: 'servers defined in webhook',
+    document: {
+      openapi: '3.1.0',
+      webhooks: {
+        servers: [],
+        newPet: {
+          post: {
+            servers: [],
+          },
+        },
+      },
+    },
+    errors: [
+      {
+        message: 'Servers should not be defined in a webhook.',
+        path: ['webhooks', 'servers'],
+        severity: DiagnosticSeverity.Warning,
+      },
+      {
+        message: 'Servers should not be defined in a webhook.',
+        path: ['webhooks', 'newPet', 'post', 'servers'],
+        severity: DiagnosticSeverity.Warning,
+      },
+    ],
+  },
+]);