Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/apidom-ls/src/config/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,9 @@ enum ApilintCodes {
OPENAPI2_REFERENCE_FIELD_$REF_FORMAT_URI = 3240100,
OPENAPI2_REFERENCE_NOT_USED = 3240300,

OPENAPI2_RESPONSES = 3250000,
OPENAPI2_RESPONSES_REQUIRED_FIELDS,

OPENAPI3_0 = 5000000,

OPENAPI3_0_OPENAPI_VALUE_PATTERN_3_0_0 = 5000100,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import allowedFields2_0Lint from './allowed-fields-2-0.ts';
import allowedFields3_0__3_1Lint from './allowed-fields-3-0--3-1.ts';
import valuesTypeLint from './values--type.ts';
import requiredFieldsLint from './required-fields.ts';

const lints = [valuesTypeLint, allowedFields2_0Lint, allowedFields3_0__3_1Lint];
const lints = [valuesTypeLint, allowedFields2_0Lint, allowedFields3_0__3_1Lint, requiredFieldsLint];

export default lints;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DiagnosticSeverity } from 'vscode-languageserver-types';

import ApilintCodes from '../../../codes.ts';
import { LinterMeta } from '../../../../apidom-language-types.ts';
import { OpenAPI2, OpenAPI3 } from '../../target-specs.ts';

const requiredFieldsLint: LinterMeta = {
code: ApilintCodes.OPENAPI2_RESPONSES_REQUIRED_FIELDS,
source: 'apilint',
message: 'Responses Object should define at least one response',
severity: DiagnosticSeverity.Error,
linterFunction: 'apilintOpenAPIEmptyResponses',
marker: 'key',
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default requiredFieldsLint;
13 changes: 13 additions & 0 deletions packages/apidom-ls/src/services/validation/linter-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1479,4 +1479,17 @@ export const standardLinterfunctions: FunctionItem[] = [
: true;
},
},
{
functionName: 'apilintOpenAPIEmptyResponses',
function: (element: Element): boolean => {
if (element && isObject(element)) {
if (!element.keys() || element.keys().length === 0) {
return false;
}

return element.keys().some((k) => typeof k !== 'string' || !k.startsWith('x-'));
}
return true;
},
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ paths:
/pets:
get:
responses:
'200':
description: ok
parameters:
- name: pathLevel
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ paths:
/pets:
get:
responses:
'200':
description: ok
parameters:
- name: pathLevel
in: query
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
swagger: '2.0'
info:
title: Test
version: 1.0.0
paths:
/:
get:
responses:
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
openapi: 3.0.0
info:
title: Test
version: 1.0.0
paths:
/:
get:
responses:
76 changes: 68 additions & 8 deletions packages/apidom-ls/test/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4205,11 +4205,11 @@ describe('apidom-ls-validate', function () {
range: {
end: {
character: 14,
line: 9,
line: 11,
},
start: {
character: 10,
line: 9,
line: 11,
},
},
severity: 1,
Expand All @@ -4222,11 +4222,11 @@ describe('apidom-ls-validate', function () {
range: {
end: {
character: 14,
line: 14,
line: 16,
},
start: {
character: 10,
line: 14,
line: 16,
},
},
severity: 1,
Expand Down Expand Up @@ -4268,11 +4268,11 @@ describe('apidom-ls-validate', function () {
range: {
end: {
character: 14,
line: 9,
line: 11,
},
start: {
character: 10,
line: 9,
line: 11,
},
},
severity: 1,
Expand All @@ -4285,11 +4285,11 @@ describe('apidom-ls-validate', function () {
range: {
end: {
character: 14,
line: 15,
line: 17,
},
start: {
character: 10,
line: 15,
line: 17,
},
},
severity: 1,
Expand Down Expand Up @@ -6099,4 +6099,64 @@ describe('apidom-ls-validate', function () {

languageService.terminate();
});

it('oas 2.0 - Responses Object should define at least one response', async function () {
const spec = fs
.readFileSync(
path.join(__dirname, 'fixtures', 'validation', 'oas', 'responses-required-fields-2-0.yaml'),
)
.toString();
const doc: TextDocument = TextDocument.create(
'foo://bar/responses-required-fields-2-0.yaml',
'yaml',
0,
spec,
);

const languageService: LanguageService = getLanguageService(contextNoSchema);

const result = await languageService.doValidation(doc);
const expected: Diagnostic[] = [
{
message: 'Responses Object should define at least one response',
severity: 1,
code: 3250001,
source: 'apilint',
range: { start: { line: 7, character: 6 }, end: { line: 7, character: 15 } },
},
];
assert.deepEqual(result, expected);

languageService.terminate();
});

it('oas 3.x - Responses Object should define at least one response', async function () {
const spec = fs
.readFileSync(
path.join(__dirname, 'fixtures', 'validation', 'oas', 'responses-required-fields-3-0.yaml'),
)
.toString();
const doc: TextDocument = TextDocument.create(
'foo://bar/responses-required-fields-3-0.yaml',
'yaml',
0,
spec,
);

const languageService: LanguageService = getLanguageService(contextNoSchema);

const result = await languageService.doValidation(doc);
const expected: Diagnostic[] = [
{
message: 'Responses Object should define at least one response',
severity: 1,
code: 3250001,
source: 'apilint',
range: { start: { line: 7, character: 6 }, end: { line: 7, character: 15 } },
},
];
assert.deepEqual(result, expected);

languageService.terminate();
});
});