diff --git a/packages/apidom-ls/src/services/validation/linter-functions.ts b/packages/apidom-ls/src/services/validation/linter-functions.ts index 1751e617e1..979fc5c8db 100644 --- a/packages/apidom-ls/src/services/validation/linter-functions.ts +++ b/packages/apidom-ls/src/services/validation/linter-functions.ts @@ -1073,46 +1073,35 @@ export const standardLinterfunctions: FunctionItem[] = [ functionName: 'apilintOpenAPIParameterFieldIsDefinedWithinPathTemplate', function: (element: Element) => { if (element.element === 'parameter') { - const parameterName = toValue((element as ObjectElement).get('name')); const parameterLocation = toValue((element as ObjectElement).get('in')); const isInPathItemElement = isArrayElement(element.parent) && includesClasses(['path-item-parameters'], element.parent); - const isChildOfOperationElement = element.parent.parent.parent.element === 'operation'; - - const getAST = (pathTemplate: string) => { - const parseResult = parse(pathTemplate); - const parts: [string, string][] = []; - parseResult.ast.translate(parts); - return parts; - }; - const pathTemplateASTIncludesParameter = (ast: [string, string][]) => - ast.findIndex( - ([name, value]) => name === 'template-expression-param-name' && value === parameterName, - ) > -1; + if (!isInPathItemElement || parameterLocation !== 'path') { + return true; + } - const getPathTemplate = (): string => { - if (isInPathItemElement) { - return toValue(element.parent.parent.parent.meta.get('path')); - } - if (isChildOfOperationElement) { - return toValue( - (element.parent.parent.parent.parent.parent.parent as MemberElement).key, - ); - } - return ''; - }; + const pathItemElement = element.parent.parent.parent; + const isPathItemPartOfPathTemplating = isStringElement(pathItemElement.meta.get('path')); - if (parameterLocation !== 'path') { + if (!isPathItemPartOfPathTemplating) { return true; } - if (isInPathItemElement || isChildOfOperationElement) { - return pathTemplateASTIncludesParameter(getAST(getPathTemplate())); - } + const pathTemplate = toValue(pathItemElement.meta.get('path')); + const parameterName = toValue((element as ObjectElement).get('name')); - return true; + const parseResult = parse(pathTemplate); + const parts: [string, string][] = []; + parseResult.ast.translate(parts); + + const pathTemplateASTIncludesParameter = (ast: [string, string][]) => + ast.findIndex( + ([name, value]) => name === 'template-expression-param-name' && value === parameterName, + ) > -1; + + return pathTemplateASTIncludesParameter(parts); } return true; }, diff --git a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-2-0.yaml b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-2-0.yaml index ff120fda83..4da1a304a4 100644 --- a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-2-0.yaml +++ b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-2-0.yaml @@ -7,15 +7,6 @@ paths: delete: summary: Delete foo bar id operationId: deleteFooBar - parameters: - - name: test_id - in: path - required: true - type: string - schema: - type: string - format: uuid - title: Test Id responses: '200': description: Successful Response diff --git a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-0.yaml b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-0.yaml index 9158f0fe31..f81f343e96 100644 --- a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-0.yaml +++ b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-0.yaml @@ -7,14 +7,6 @@ paths: delete: summary: Delete foo bar id operationId: deleteFooBar - parameters: - - name: test_id - in: path - required: true - schema: - type: string - format: uuid - title: Test Id responses: '200': description: Successful Response diff --git a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-1.yaml b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-1.yaml index 0b74d9c7e6..10ba12c621 100644 --- a/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-1.yaml +++ b/packages/apidom-ls/test/fixtures/validation/oas/parameter-defined-within-path-template-3-1.yaml @@ -7,14 +7,6 @@ paths: delete: summary: Delete foo bar id operationId: deleteFooBar - parameters: - - name: test_id - in: path - required: true - schema: - type: string - format: uuid - title: Test Id responses: '200': description: Successful Response diff --git a/packages/apidom-ls/test/validate.ts b/packages/apidom-ls/test/validate.ts index c60288a43a..1926f37276 100644 --- a/packages/apidom-ls/test/validate.ts +++ b/packages/apidom-ls/test/validate.ts @@ -3580,14 +3580,7 @@ describe('apidom-ls-validate', function () { const result = await languageService.doValidation(doc, validationContext); const expected: Diagnostic[] = [ { - range: { start: { line: 10, character: 8 }, end: { line: 17, character: 24 } }, - message: 'parameter is not defined within path template', - severity: 1, - code: 3102000, - source: 'apilint', - }, - { - range: { start: { line: 25, character: 8 }, end: { line: 32, character: 23 } }, + range: { start: { line: 16, character: 8 }, end: { line: 23, character: 23 } }, message: 'parameter is not defined within path template', severity: 1, code: 3102000, @@ -3629,14 +3622,7 @@ describe('apidom-ls-validate', function () { const result = await languageService.doValidation(doc, validationContext); const expected: Diagnostic[] = [ { - range: { start: { line: 10, character: 8 }, end: { line: 16, character: 24 } }, - message: 'parameter is not defined within path template', - severity: 1, - code: 3102000, - source: 'apilint', - }, - { - range: { start: { line: 24, character: 8 }, end: { line: 30, character: 23 } }, + range: { start: { line: 16, character: 8 }, end: { line: 22, character: 23 } }, message: 'parameter is not defined within path template', severity: 1, code: 3102000, @@ -3678,28 +3664,12 @@ describe('apidom-ls-validate', function () { const result = await languageService.doValidation(doc, validationContext); const expected: Diagnostic[] = [ { - range: { start: { line: 10, character: 8 }, end: { line: 16, character: 24 } }, + range: { start: { line: 16, character: 8 }, end: { line: 22, character: 23 } }, message: 'parameter is not defined within path template', severity: 1, code: 3102000, source: 'apilint', }, - { - code: 3102000, - message: 'parameter is not defined within path template', - range: { - end: { - character: 23, - line: 30, - }, - start: { - character: 8, - line: 24, - }, - }, - severity: 1, - source: 'apilint', - }, ]; assert.deepEqual(result, expected as Diagnostic[]);