-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow linting OpenAPI path templates #3532
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import valueWellFormedLint from './value--well-formed'; | ||
import valueValidLint from './value--valid'; | ||
|
||
const lints = [valueWellFormedLint, valueValidLint]; | ||
|
||
export default lints; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { DiagnosticSeverity } from 'vscode-languageserver-types'; | ||
|
||
import ApilintCodes from '../../../codes'; | ||
import { LinterMeta } from '../../../../apidom-language-types'; | ||
import { OpenAPI } from '../../target-specs'; | ||
|
||
const valueValidLint: LinterMeta = { | ||
code: ApilintCodes.OPENAPI2_PATH_TEMPLATE_VALUE_VALID, | ||
source: 'apilint', | ||
message: 'path template expressions is not matched with Parameter Object(s)', | ||
severity: DiagnosticSeverity.Error, | ||
linterFunction: 'apilintOpenAPIPathTemplateValid', | ||
marker: 'value', | ||
targetSpecs: OpenAPI, | ||
conditions: [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to validate matching of Paramater Objects only when the path template is well formed and contains at least one |
||
{ | ||
function: 'apilintOpenAPIPathTemplateWellFormed', | ||
params: [true], | ||
}, | ||
], | ||
}; | ||
|
||
export default valueValidLint; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { DiagnosticSeverity } from 'vscode-languageserver-types'; | ||
|
||
import ApilintCodes from '../../../codes'; | ||
import { LinterMeta } from '../../../../apidom-language-types'; | ||
import { OpenAPI } from '../../target-specs'; | ||
|
||
const valueWellFormedLint: LinterMeta = { | ||
code: ApilintCodes.OPENAPI2_PATH_TEMPLATE_VALUE_WELL_FORMED, | ||
source: 'apilint', | ||
message: "'path' must begin with '/' and be relative to an individual endpoint", | ||
severity: DiagnosticSeverity.Error, | ||
linterFunction: 'apilintOpenAPIPathTemplateWellFormed', | ||
linterParams: [false], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we don't care if path template contains at least one template expression, as long as the entire path template is well formed. |
||
marker: 'value', | ||
targetSpecs: OpenAPI, | ||
}; | ||
|
||
export default valueWellFormedLint; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import lint from './lint'; | ||
import { FormatMeta } from '../../../apidom-language-types'; | ||
|
||
const meta: FormatMeta = { | ||
lint, | ||
}; | ||
|
||
export default meta; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
import keysPatternLint from './keys--pattern'; | ||
import valuesTypeLint from './values--type'; | ||
|
||
const lints = [valuesTypeLint, keysPatternLint]; | ||
const lints = [valuesTypeLint]; | ||
|
||
export default lints; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,14 @@ import { | |
Element, | ||
ArrayElement, | ||
MemberElement, | ||
isStringElement, | ||
filter, | ||
toValue, | ||
ArraySlice, | ||
ObjectElement, | ||
} from '@swagger-api/apidom-core'; | ||
import { CompletionItem } from 'vscode-languageserver-types'; | ||
import { test } from 'openapi-path-templating'; | ||
|
||
// eslint-disable-next-line import/no-cycle | ||
import { | ||
|
@@ -993,4 +995,23 @@ export const standardLinterfunctions: FunctionItem[] = [ | |
return true; | ||
}, | ||
}, | ||
{ | ||
functionName: 'apilintOpenAPIPathTemplateWellFormed', | ||
function: (element: Element, strict = false) => { | ||
if (isStringElement(element)) { | ||
const pathTemplate = toValue(element); | ||
return test(pathTemplate, { strict }); | ||
} | ||
return true; | ||
}, | ||
}, | ||
{ | ||
functionName: 'apilintOpenAPIPathTemplateValid', | ||
function: (element: Element) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where you need to implement the logic of matching template expressions against the Parameter Objects. |
||
if (isStringElement(element)) { | ||
return true; | ||
} | ||
return true; | ||
}, | ||
}, | ||
]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import stampit from 'stampit'; | ||
import { test, always } from 'ramda'; | ||
import { T as stubTrue, always } from 'ramda'; | ||
import { ObjectElement, StringElement, cloneDeep } from '@swagger-api/apidom-core'; | ||
|
||
import PathsElement from '../../../../elements/Paths'; | ||
|
@@ -10,7 +10,7 @@ import { isPathItemElement } from '../../../../predicates'; | |
|
||
const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { | ||
props: { | ||
fieldPatternPredicate: test(/^\/(?<path>.*)$/), | ||
fieldPatternPredicate: stubTrue, | ||
specPath: always(['document', 'objects', 'PathItem']), | ||
canSupportSpecificationExtensions: true, | ||
}, | ||
|
@@ -26,6 +26,8 @@ const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { | |
this.element | ||
.filter(isPathItemElement) | ||
.forEach((pathItemElement: PathItemElement, key: StringElement) => { | ||
key.classes.push('openapi-path-template'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attaching metadata classes. |
||
key.classes.push('path-template'); | ||
pathItemElement.setMetaProperty('path', cloneDeep(key)); | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we're attaching our meta (containing linting rules) to the
path-template
meta class.