Skip to content

Commit cbb3446

Browse files
feat: add ref validation rules (#4989)
1 parent 2273a1b commit cbb3446

33 files changed

+844
-19
lines changed

packages/apidom-ls/src/config/codes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@ enum ApilintCodes {
843843

844844
OPENAPI2_REFERENCE = 3240000,
845845
OPENAPI2_REFERENCE_FIELD_$REF_FORMAT_URI = 3240100,
846+
OPENAPI2_REFERENCE_NOT_USED = 3240300,
846847

847848
OPENAPI3_0 = 5000000,
848849

@@ -1070,6 +1071,11 @@ enum ApilintCodes {
10701071
OPENAPI3_0_REFERENCE = 5260000,
10711072
OPENAPI3_0_REFERENCE_FIELD_$REF_FORMAT_URI = 5260100,
10721073
OPENAPI3_0_REFERENCE_FIELD_$REF_NO_SIBLINGS,
1074+
OPENAPI3_0_REFERENCE_FIELD_$REF_REQUEST_BODIES = 5260200,
1075+
OPENAPI3_0_REFERENCE_FIELD_$REF_REQUEST_BODIES_NAMING,
1076+
OPENAPI3_0_REFERENCE_FIELD_$REF_REQUEST_BODIES_NAMING_SCHEMA,
1077+
OPENAPI3_0_REFERENCE_FIELD_$REF_HEADER = 5260300,
1078+
OPENAPI3_0_REFERENCE_FIELD_$REF_PARAMETER = 5260400,
10731079

10741080
OPENAPI3_0_LINK = 5270000,
10751081
OPENAPI3_0_LINK_FIELD_OPERATION_REF_FORMAT_URI = 5270100,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
2+
3+
import ApilintCodes from '../../../codes.ts';
4+
import { LinterMeta } from '../../../../apidom-language-types.ts';
5+
import { OpenAPI2, OpenAPI3, OpenAPI31 } from '../../../openapi/target-specs.ts';
6+
7+
const $refNotUsedLint: LinterMeta = {
8+
code: ApilintCodes.OPENAPI2_REFERENCE_NOT_USED,
9+
source: 'apilint',
10+
message: 'Definition was declared but never used in document',
11+
severity: DiagnosticSeverity.Warning,
12+
linterFunction: 'apilintReferenceNotUsed',
13+
linterParams: ['string'],
14+
marker: 'key',
15+
data: {},
16+
targetSpecs: [...OpenAPI2, ...OpenAPI3, ...OpenAPI31],
17+
};
18+
19+
export default $refNotUsedLint;

packages/apidom-ls/src/config/common/schema/lint/$ref--valid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { OpenAPI2, OpenAPI3 } from '../../../openapi/target-specs.ts';
88
const $refValidLint: LinterMeta = {
99
code: ApilintCodes.SCHEMA_REF,
1010
source: 'apilint',
11-
message: "'$ref' value must be a valid URI-reference",
11+
message: "'$ref' value must be an RFC3986-compliant URI reference",
1212
severity: DiagnosticSeverity.Error,
13-
linterFunction: 'apilintValidURI',
13+
linterFunction: 'apilintValidURI_RFC3986',
1414
marker: 'value',
1515
target: '$ref',
1616
data: {},
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
2+
3+
import ApilintCodes from '../../../codes.ts';
4+
import { LinterMeta } from '../../../../apidom-language-types.ts';
5+
import { OpenAPI3 } from '../../../openapi/target-specs.ts';
6+
7+
const $ref3RequestBodiesLint: LinterMeta = {
8+
code: ApilintCodes.OPENAPI3_0_REFERENCE_FIELD_$REF_REQUEST_BODIES,
9+
source: 'apilint',
10+
message:
11+
'requestBody schema $refs must point to a position where a Schema Object can be legally placed',
12+
severity: DiagnosticSeverity.Error,
13+
linterFunction: 'parentExistFields',
14+
linterParams: [['requestBody']],
15+
conditions: [
16+
{
17+
targets: [{ path: '$ref' }],
18+
function: 'apilintValueRegex',
19+
params: ['^(?!.*#/components/schemas).*$'],
20+
},
21+
],
22+
marker: 'value',
23+
target: '$ref',
24+
data: {},
25+
targetSpecs: OpenAPI3,
26+
};
27+
28+
export default $ref3RequestBodiesLint;

packages/apidom-ls/src/config/common/schema/lint/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import allowedFieldsOpenAPI3_0Lint from './allowed-fields-openapi-3-0.ts';
33
import $idFormatURILint from './$id--format-uri.ts';
44
import $refValidLint from './$ref--valid.ts';
55
import $refNoSiblingsLint from './$ref--no-siblings.ts';
6+
import $ref3RequestBodiesLint from './$ref-3-0--request-bodies.ts';
67
import additionalItemsNonArrayLint from './additional-items--non-array.ts';
78
import additionalItemsTypeLint from './additional-items--type.ts';
89
import additionalItemsTypeOpenAPI3_1__AsyncAPI2Lint from './additional-items--type-openapi-3-1--asyncapi-2.ts';
@@ -81,13 +82,16 @@ import uniqueItemsNonArrayLint from './unique-items--non-array.ts';
8182
import uniqueItemsTypeLint from './unique-items--type.ts';
8283
import writeOnlyTypeLint from './write-only--type.ts';
8384
import exampleDeprecatedLint from './example--deprecated.ts';
85+
import $refNotUsedLint from './$ref--not-used.ts';
8486

8587
const schemaLints = [
8688
allowedFieldsOpenAPI2_0Lint,
8789
allowedFieldsOpenAPI3_0Lint,
8890
$idFormatURILint,
8991
$refValidLint,
9092
$refNoSiblingsLint,
93+
$refNotUsedLint,
94+
$ref3RequestBodiesLint,
9195
additionalItemsNonArrayLint,
9296
additionalItemsTypeLint,
9397
additionalItemsTypeOpenAPI3_1__AsyncAPI2Lint,
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import valuesTypeLint from './values--type.ts';
2+
import $refNotUsedLint from '../../../common/schema/lint/$ref--not-used.ts';
23

3-
const lints = [valuesTypeLint];
4+
const lints = [valuesTypeLint, $refNotUsedLint];
45

56
export default lints;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
2+
3+
import ApilintCodes from '../../../codes.ts';
4+
import { LinterMeta } from '../../../../apidom-language-types.ts';
5+
import { OpenAPI3 } from '../../target-specs.ts';
6+
7+
const $ref3HeaderNamingLint: LinterMeta = {
8+
code: ApilintCodes.OPENAPI3_0_REFERENCE_FIELD_$REF_HEADER,
9+
source: 'apilint',
10+
message: 'OAS3 header $Ref should point to Header Object',
11+
severity: DiagnosticSeverity.Error,
12+
linterFunction: 'parentExistFields',
13+
linterParams: [['header']],
14+
conditions: [
15+
{
16+
targets: [{ path: '$ref' }],
17+
function: 'apilintValueRegex',
18+
params: ['^(?!.*#/components/headers).*$'],
19+
},
20+
],
21+
marker: 'value',
22+
target: '$ref',
23+
data: {},
24+
targetSpecs: OpenAPI3,
25+
};
26+
27+
export default $ref3HeaderNamingLint;

packages/apidom-ls/src/config/openapi/header/lint/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ import minItemsTypeLint from './min-items--type.ts';
3535
import uniqueItemsTypeLint from './unique-items--type.ts';
3636
import enumTypeLint from './enum--type.ts';
3737
import multipleOfTypeLint from './multiple-of--type.ts';
38+
import $ref3HeaderNamingLint from './$ref-3-0--header.ts';
3839

3940
const lints = [
41+
$ref3HeaderNamingLint,
4042
descriptionTypeLint,
4143
requiredTypeLint,
4244
deprecatedTypeLint,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
2+
3+
import ApilintCodes from '../../../codes.ts';
4+
import { LinterMeta } from '../../../../apidom-language-types.ts';
5+
import { OpenAPI3 } from '../../target-specs.ts';
6+
7+
const $ref3ParameterNamingLint: LinterMeta = {
8+
code: ApilintCodes.OPENAPI3_0_REFERENCE_FIELD_$REF_PARAMETER,
9+
source: 'apilint',
10+
message: 'OAS3 parameter $Ref should point to Parameter Object',
11+
severity: DiagnosticSeverity.Error,
12+
linterFunction: 'apilintValueRegex',
13+
linterParams: ['^(.*#/components/parameters).*$'],
14+
marker: 'value',
15+
target: '$ref',
16+
conditions: [
17+
{
18+
targets: [{ path: '$ref' }],
19+
function: 'parentExistFields',
20+
params: [['paths']],
21+
},
22+
],
23+
data: {},
24+
targetSpecs: OpenAPI3,
25+
};
26+
27+
export default $ref3ParameterNamingLint;

packages/apidom-ls/src/config/openapi/parameter/lint/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ import inAuthorizationLint from './in--authorization.ts';
4747
import inContentTypeLint from './in--content-type.ts';
4848
import inAcceptLint from './in--accept.ts';
4949
import inMultipleBody from './in--multiple-body.ts';
50+
import $ref3ParameterNamingLint from './$ref-3-0--parameter.ts';
5051

5152
const lints = [
53+
$ref3ParameterNamingLint,
5254
nameTypeLint,
5355
nameRequiredLint,
5456
inEquals2_0Lint,

0 commit comments

Comments
 (0)