Skip to content

Commit ad9aafe

Browse files
authored
feat: add excludedPaths option to no-http-verbs-in-paths rule (#2719)
1 parent b849ef5 commit ad9aafe

4 files changed

Lines changed: 70 additions & 5 deletions

File tree

.changeset/warm-paths-glow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@redocly/openapi-core": minor
3+
---
4+
5+
Added `excludedPaths` option to the `no-http-verbs-in-paths` rule, allowing specific paths to be excluded from evaluation.

docs/@v2/rules/oas/no-http-verbs-in-paths.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ With the `splitIntoWords` option enabled, "posters" is identified as a resource
4545

4646
## Configuration
4747

48-
| Option | Type | Description |
49-
| -------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
50-
| severity | string | Possible values: `off`, `warn`, `error`. Default `off` (in `recommended` configuration). |
51-
| splitIntoWords | boolean | Matches http verbs when the string is split into words based on casing. This can reduce false positives. Default **false**. |
48+
| Option | Type | Description |
49+
| -------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |
50+
| severity | string | Possible values: `off`, `warn`, `error`. Default `off` (in `recommended` configuration). |
51+
| splitIntoWords | boolean | Matches http verbs when the string is split into words based on casing. This can reduce false positives. Default **false**. |
52+
| excludedPaths | [string] | List of paths to exclude from the check. Use exact path strings (e.g. `/token`). Default **[]**. |
5253

5354
An example configuration:
5455

@@ -66,6 +67,17 @@ rules:
6667
splitIntoWords: true
6768
```
6869

70+
An example configuration with `excludedPaths` to allow specific paths that intentionally contain HTTP verbs:
71+
72+
```yaml
73+
rules:
74+
no-http-verbs-in-paths:
75+
severity: error
76+
excludedPaths:
77+
- /token
78+
- /oauth/callback
79+
```
80+
6981
## Examples
7082

7183
Given this configuration:

packages/core/src/rules/common/__tests__/no-http-verbs-in-paths.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,51 @@ describe('no-http-verbs-in-paths', () => {
6161
]
6262
`);
6363
});
64+
65+
it('should not report on excluded paths', async () => {
66+
const document = parseYamlToDocument(
67+
outdent`
68+
openapi: 3.1.0
69+
paths:
70+
/data/post:
71+
get:
72+
summary: Contains http verb post
73+
/get/data:
74+
get:
75+
summary: Contains http verb get
76+
`,
77+
'foobar.yaml'
78+
);
79+
80+
const results = await lintDocument({
81+
externalRefResolver: new BaseResolver(),
82+
document,
83+
config: await createConfig({
84+
rules: {
85+
'no-http-verbs-in-paths': {
86+
severity: 'error',
87+
excludedPaths: ['/data/post'],
88+
},
89+
},
90+
}),
91+
});
92+
93+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
94+
[
95+
{
96+
"location": [
97+
{
98+
"pointer": "#/paths/~1get~1data",
99+
"reportOnKey": true,
100+
"source": "foobar.yaml",
101+
},
102+
],
103+
"message": "path \`/get/data\` should not contain http verb get",
104+
"ruleId": "no-http-verbs-in-paths",
105+
"severity": "error",
106+
"suggest": [],
107+
},
108+
]
109+
`);
110+
});
64111
});

packages/core/src/rules/common/no-http-verbs-in-paths.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import type { UserContext } from '../../walk.js';
77

88
const httpMethods = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace'];
99

10-
export const NoHttpVerbsInPaths: Oas3Rule | Oas2Rule = ({ splitIntoWords }) => {
10+
export const NoHttpVerbsInPaths: Oas3Rule | Oas2Rule = ({ splitIntoWords, excludedPaths }) => {
1111
return {
1212
PathItem(_path: Oas2PathItem | Oas3PathItem, { key, report, location }: UserContext) {
1313
const pathKey = key.toString();
1414
if (!pathKey.startsWith('/')) return;
15+
if (excludedPaths?.some((excludedPath: string) => pathKey === excludedPath)) return;
1516
const pathSegments = pathKey.split('/');
1617

1718
for (const pathSegment of pathSegments) {

0 commit comments

Comments
 (0)