From 2c591b6001dbe9e0c777b3918f29981ccdeab904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Thu, 4 Jan 2024 10:48:25 +0100 Subject: [PATCH] feat(ls): add rules for OpenAPI 2.0 Response Object (#3627) Refs #3607 --- packages/apidom-ls/src/config/codes.ts | 7 +++ .../src/config/openapi/response/completion.ts | 60 ++++++++++++++++++- .../config/openapi/response/documentation.ts | 26 +++++++- .../response/lint/allowed-fields-2-0.ts | 19 ++++++ .../response/lint/description--required.ts | 6 +- .../response/lint/description--type.ts | 6 +- .../openapi/response/lint/examples--type.ts | 21 +++++++ .../openapi/response/lint/headers--type.ts | 21 +++++++ .../src/config/openapi/response/lint/index.ts | 8 +++ .../openapi/response/lint/schema--type.ts | 20 +++++++ packages/apidom-ls/test/ads.ts | 12 ++-- ...eter-defined-within-path-template-2-0.yaml | 19 ++---- .../oas/path-template-all-defined-2-0.yaml | 12 ---- packages/apidom-ls/test/validate.ts | 10 ++-- 14 files changed, 200 insertions(+), 47 deletions(-) create mode 100644 packages/apidom-ls/src/config/openapi/response/lint/allowed-fields-2-0.ts create mode 100644 packages/apidom-ls/src/config/openapi/response/lint/examples--type.ts create mode 100644 packages/apidom-ls/src/config/openapi/response/lint/headers--type.ts create mode 100644 packages/apidom-ls/src/config/openapi/response/lint/schema--type.ts diff --git a/packages/apidom-ls/src/config/codes.ts b/packages/apidom-ls/src/config/codes.ts index f5b1bc48c..2b3925e06 100644 --- a/packages/apidom-ls/src/config/codes.ts +++ b/packages/apidom-ls/src/config/codes.ts @@ -753,6 +753,13 @@ enum ApilintCodes { OPENAPI2_ITEMS_FIELD_ENUM_TYPE = 3111200, OPENAPI2_ITEMS_FIELD_MULTIPLE_OF_TYPE = 3111300, + OPENAPI2_RESPONSE = 3120000, + OPENAPI2_RESPONSE_FIELD_DESCRIPTION_TYPE = 3120100, + OPENAPI2_RESPONSE_FIELD_DESCRIPTION_REQUIRED, + OPENAPI2_RESPONSE_FIELD_SCHEMA_TYPE = 3120200, + OPENAPI2_RESPONSE_FIELD_HEADERS_TYPE = 3120300, + OPENAPI2_RESPONSE_FIELD_EXAMPLES_TYPE = 3120400, + OPENAPI3_0 = 5000000, OPENAPI3_0_OPENAPI_VALUE_PATTERN_3_0_0 = 5000100, diff --git a/packages/apidom-ls/src/config/openapi/response/completion.ts b/packages/apidom-ls/src/config/openapi/response/completion.ts index a033327c6..271c07255 100644 --- a/packages/apidom-ls/src/config/openapi/response/completion.ts +++ b/packages/apidom-ls/src/config/openapi/response/completion.ts @@ -3,7 +3,7 @@ import { CompletionFormat, CompletionType, } from '../../../apidom-language-types'; -import { OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs'; +import { OpenAPI2, OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs'; const completion: ApidomCompletionItem[] = [ { @@ -17,7 +17,21 @@ const completion: ApidomCompletionItem[] = [ kind: 'markdown', value: 'A reference to a Response.', }, - targetSpecs: OpenAPI3, + targetSpecs: [...OpenAPI2, ...OpenAPI3], + }, + { + label: 'description', + insertText: 'description', + kind: 14, + format: CompletionFormat.QUOTED, + type: CompletionType.PROPERTY, + insertTextFormat: 2, + documentation: { + kind: 'markdown', + value: + '**Required.** A short description of the response. [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) can be used for rich text representation.', + }, + targetSpecs: OpenAPI2, }, { label: 'description', @@ -33,6 +47,34 @@ const completion: ApidomCompletionItem[] = [ }, targetSpecs: OpenAPI3, }, + { + label: 'schema', + insertText: 'schema', + kind: 14, + format: CompletionFormat.OBJECT, + type: CompletionType.PROPERTY, + insertTextFormat: 2, + documentation: { + kind: 'markdown', + value: + '[Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject)\n\\\n\\\nA definition of the response structure. It can be a primitive, an array or an object. If this field does not exist, it means no content is returned as part of the response. As an extension to the [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject), its root `type` value may also be `"file"`. This SHOULD be accompanied by a relevant `produces` mime-type.', + }, + targetSpecs: OpenAPI2, + }, + { + label: 'headers', + insertText: 'headers', + kind: 14, + format: CompletionFormat.OBJECT, + type: CompletionType.PROPERTY, + insertTextFormat: 2, + documentation: { + kind: 'markdown', + value: + '[Headers Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#headersObject)\n\\\n\\\nA list of headers that are sent with the response.', + }, + targetSpecs: OpenAPI2, + }, { label: 'headers', insertText: 'headers', @@ -61,6 +103,20 @@ const completion: ApidomCompletionItem[] = [ }, targetSpecs: OpenAPI31, }, + { + label: 'examples', + insertText: 'examples', + kind: 14, + format: CompletionFormat.OBJECT, + type: CompletionType.PROPERTY, + insertTextFormat: 2, + documentation: { + kind: 'markdown', + value: + '[Example Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#exampleObject)\n\\\n\\\nAn example of the response message.', + }, + targetSpecs: OpenAPI2, + }, { label: 'content', insertText: 'content', diff --git a/packages/apidom-ls/src/config/openapi/response/documentation.ts b/packages/apidom-ls/src/config/openapi/response/documentation.ts index 82e3bfb2a..6ee566f40 100644 --- a/packages/apidom-ls/src/config/openapi/response/documentation.ts +++ b/packages/apidom-ls/src/config/openapi/response/documentation.ts @@ -1,4 +1,4 @@ -import { OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs'; +import { OpenAPI2, OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs'; const documentation = [ { @@ -6,6 +6,21 @@ const documentation = [ docs: '**REQUIRED**. A description of the response. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.', targetSpecs: OpenAPI3, }, + { + target: 'description', + docs: '**Required.** A short description of the response. [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) can be used for rich text representation.', + targetSpecs: OpenAPI2, + }, + { + target: 'schema', + docs: '[Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject)\n\\\n\\\nA definition of the response structure. It can be a primitive, an array or an object. If this field does not exist, it means no content is returned as part of the response. As an extension to the [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject), its root `type` value may also be `"file"`. This SHOULD be accompanied by a relevant `produces` mime-type.', + targetSpecs: OpenAPI2, + }, + { + target: 'headers', + docs: '[Headers Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#headersObject)\n\\\n\\\nA list of headers that are sent with the response.', + targetSpecs: OpenAPI2, + }, { target: 'headers', docs: 'Map[`string`, [Header Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#headerObject) | [Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#referenceObject)]\n\\\n\\\nMaps a header name to its definition. [RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case insensitive. If a response header is defined with the name `"Content-Type"`, it SHALL be ignored.', @@ -16,6 +31,11 @@ const documentation = [ docs: 'Map[`string`, [Header Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#headerObject) | [Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#referenceObject)]\n\\\n\\\nMaps a header name to its definition. [RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case insensitive. If a response header is defined with the name `"Content-Type"`, it SHALL be ignored.', targetSpecs: OpenAPI31, }, + { + target: 'examples', + docs: '[Example Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#exampleObject)\n\\\n\\\nAn example of the response message.', + targetSpecs: OpenAPI2, + }, { target: 'content', docs: 'Map[`string`, [Media Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#mediaTypeObject)]\n\\\n\\\nA map containing descriptions of potential response payloads. The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D) and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*', @@ -36,6 +56,10 @@ const documentation = [ docs: 'Map[`string`, [Link Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#linkObject) | [Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#referenceObject)]\n\\\n\\\nA map of operations links that can be followed from the response. The key of the map is a short name for the link, following the naming constraints of the names for [Component Objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#componentsObject).', targetSpecs: OpenAPI31, }, + { + docs: '#### [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#response-object)\n\nDescribes a single response from an API Operation.\n\n##### Fixed Fields\nField Name | Type | Description\n---|:---:|---\ndescription | `string` | **Required.** A short description of the response. [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) can be used for rich text representation.\nschema | [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject) | A definition of the response structure. It can be a primitive, an array or an object. If this field does not exist, it means no content is returned as part of the response. As an extension to the [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject), its root `type` value may also be `"file"`. This SHOULD be accompanied by a relevant `produces` mime-type.\nheaders | [Headers Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#headersObject) | A list of headers that are sent with the response.\nexamples | [Example Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#exampleObject) | An example of the response message.\n\n##### Patterned Objects\n\nField Pattern | Type | Description\n---|:---:|---\n^x- | Any | Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See [Vendor Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#vendorExtensions) for further details.\n\n##### Response Object Examples\n\nResponse of an array of a complex type:\n\n```js\n{\n "description": "A complex object array response",\n "schema": {\n "type": "array",\n "items": {\n "$ref": "#/definitions/VeryComplexType"\n }\n }\n}\n```\n\n\n\\\nYAML\n```yaml\ndescription: A complex object array response\nschema:\n type: array\n items:\n $ref: \'#/definitions/VeryComplexType\'\n```\n\nResponse with a string type:\n\n```js\n{\n "description": "A simple string response",\n "schema": {\n "type": "string"\n }\n}\n```\n\n```yaml\ndescription: A simple string response\nschema:\n type: string\n```\n\nResponse with headers:\n\n```js\n{\n "description": "A simple string response",\n "schema": {\n "type": "string"\n },\n "headers": {\n "X-Rate-Limit-Limit": {\n "description": "The number of allowed requests in the current period",\n "type": "integer"\n },\n "X-Rate-Limit-Remaining": {\n "description": "The number of remaining requests in the current period",\n "type": "integer"\n },\n "X-Rate-Limit-Reset": {\n "description": "The number of seconds left in the current period",\n "type": "integer"\n }\n }\n}\n```\n\n```yaml\ndescription: A simple string response\nschema:\n type: string\nheaders:\n X-Rate-Limit-Limit:\n description: The number of allowed requests in the current period\n type: integer\n X-Rate-Limit-Remaining:\n description: The number of remaining requests in the current period\n type: integer\n X-Rate-Limit-Reset:\n description: The number of seconds left in the current period\n type: integer\n```\n\nResponse with no return value:\n\n```js\n{\n "description": "object created"\n}\n```\n\n```yaml\ndescription: object created\n```', + targetSpecs: OpenAPI2, + }, { docs: '#### [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responseObject)\nDescribes a single response from an API Operation, including design-time, static\n`links` to operations based on the response.\n\n##### Fixed Fields\nField Name | Type | Description\n---|:---:|---\ndescription | `string` | **REQUIRED**. A short description of the response. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.\nheaders | Map[`string`, [Header Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#headerObject) \\| [Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#referenceObject)] | Maps a header name to its definition. [RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case insensitive. If a response header is defined with the name `"Content-Type"`, it SHALL be ignored.\ncontent | Map[`string`, [Media Type Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#mediaTypeObject)] | A map containing descriptions of potential response payloads. The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D) and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*\nlinks | Map[`string`, [Link Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#linkObject) \\| [Reference Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#referenceObject)] | A map of operations links that can be followed from the response. The key of the map is a short name for the link, following the naming constraints of the names for [Component Objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#componentsObject).\n\nThis object MAY be extended with [Specification Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions).\n\n##### Response Object Examples\n\nResponse of an array of a complex type:\n\n\n\\\nJSON\n```json\n{\n "description": "A complex object array response",\n "content": {\n "application/json": {\n "schema": {\n "type": "array",\n "items": {\n "$ref": "#/components/schemas/VeryComplexType"\n }\n }\n }\n }\n}\n```\n\n\n\\\nYAML\n```yaml\ndescription: A complex object array response\ncontent:\n application/json:\n schema:\n type: array\n items:\n $ref: \'#/components/schemas/VeryComplexType\'\n```\n\nResponse with a string type:\n\n```json\n{\n "description": "A simple string response",\n "content": {\n "text/plain": {\n "schema": {\n "type": "string"\n }\n }\n }\n\n}\n```\n\n```yaml\ndescription: A simple string response\ncontent:\n text/plain:\n schema:\n type: string\n```\n\nPlain text response with headers:\n\n```json\n{\n "description": "A simple string response",\n "content": {\n "text/plain": {\n "schema": {\n "type": "string",\n "example": "whoa!"\n }\n }\n },\n "headers": {\n "X-Rate-Limit-Limit": {\n "description": "The number of allowed requests in the current period",\n "schema": {\n "type": "integer"\n }\n },\n "X-Rate-Limit-Remaining": {\n "description": "The number of remaining requests in the current period",\n "schema": {\n "type": "integer"\n }\n },\n "X-Rate-Limit-Reset": {\n "description": "The number of seconds left in the current period",\n "schema": {\n "type": "integer"\n }\n }\n }\n}\n```\n\n```yaml\ndescription: A simple string response\ncontent:\n text/plain:\n schema:\n type: string\n example: \'whoa!\'\nheaders:\n X-Rate-Limit-Limit:\n description: The number of allowed requests in the current period\n schema:\n type: integer\n X-Rate-Limit-Remaining:\n description: The number of remaining requests in the current period\n schema:\n type: integer\n X-Rate-Limit-Reset:\n description: The number of seconds left in the current period\n schema:\n type: integer\n```\n\nResponse with no return value:\n\n```json\n{\n "description": "object created"\n}\n```\n\n```yaml\ndescription: object created\n```', targetSpecs: OpenAPI30, diff --git a/packages/apidom-ls/src/config/openapi/response/lint/allowed-fields-2-0.ts b/packages/apidom-ls/src/config/openapi/response/lint/allowed-fields-2-0.ts new file mode 100644 index 000000000..412feb53d --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/response/lint/allowed-fields-2-0.ts @@ -0,0 +1,19 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI2 } from '../../target-specs'; + +// eslint-disable-next-line @typescript-eslint/naming-convention +const allowedFields2_0Lint: LinterMeta = { + code: ApilintCodes.NOT_ALLOWED_FIELDS, + source: 'apilint', + message: 'Object includes not allowed fields', + severity: DiagnosticSeverity.Error, + linterFunction: 'allowedFields', + linterParams: [['description', 'schema', 'headers', 'examples', '$ref'], 'x-'], + marker: 'key', + targetSpecs: OpenAPI2, +}; + +export default allowedFields2_0Lint; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/description--required.ts b/packages/apidom-ls/src/config/openapi/response/lint/description--required.ts index 17334fd1a..3569a3abe 100644 --- a/packages/apidom-ls/src/config/openapi/response/lint/description--required.ts +++ b/packages/apidom-ls/src/config/openapi/response/lint/description--required.ts @@ -2,10 +2,10 @@ import { DiagnosticSeverity } from 'vscode-languageserver-types'; import ApilintCodes from '../../../codes'; import { LinterMeta } from '../../../../apidom-language-types'; -import { OpenAPI3 } from '../../target-specs'; +import { OpenAPI2, OpenAPI3 } from '../../target-specs'; const descriptionRequiredLint: LinterMeta = { - code: ApilintCodes.OPENAPI3_0_RESPONSE_FIELD_DESCRIPTION_REQUIRED, + code: ApilintCodes.OPENAPI2_RESPONSE_FIELD_DESCRIPTION_REQUIRED, source: 'apilint', message: "should always have a 'description'", severity: DiagnosticSeverity.Error, @@ -28,7 +28,7 @@ const descriptionRequiredLint: LinterMeta = { params: ['$ref'], }, ], - targetSpecs: OpenAPI3, + targetSpecs: [...OpenAPI2, ...OpenAPI3], }; export default descriptionRequiredLint; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/description--type.ts b/packages/apidom-ls/src/config/openapi/response/lint/description--type.ts index a8403b4c7..77e3b6af3 100644 --- a/packages/apidom-ls/src/config/openapi/response/lint/description--type.ts +++ b/packages/apidom-ls/src/config/openapi/response/lint/description--type.ts @@ -2,10 +2,10 @@ import { DiagnosticSeverity } from 'vscode-languageserver-types'; import ApilintCodes from '../../../codes'; import { LinterMeta } from '../../../../apidom-language-types'; -import { OpenAPI3 } from '../../target-specs'; +import { OpenAPI2, OpenAPI3 } from '../../target-specs'; const descriptionTypeLint: LinterMeta = { - code: ApilintCodes.OPENAPI3_0_RESPONSE_FIELD_DESCRIPTION_TYPE, + code: ApilintCodes.OPENAPI2_RESPONSE_FIELD_DESCRIPTION_TYPE, source: 'apilint', message: 'description must be a string', severity: DiagnosticSeverity.Error, @@ -14,7 +14,7 @@ const descriptionTypeLint: LinterMeta = { marker: 'value', target: 'description', data: {}, - targetSpecs: OpenAPI3, + targetSpecs: [...OpenAPI2, ...OpenAPI3], }; export default descriptionTypeLint; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/examples--type.ts b/packages/apidom-ls/src/config/openapi/response/lint/examples--type.ts new file mode 100644 index 000000000..210bb9a4e --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/response/lint/examples--type.ts @@ -0,0 +1,21 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI2 } from '../../target-specs'; + +const examplesTypeLint: LinterMeta = { + code: ApilintCodes.OPENAPI2_RESPONSE_FIELD_EXAMPLES_TYPE, + source: 'apilint', + message: '"examples" must be an object', + severity: DiagnosticSeverity.Error, + linterFunction: 'apilintElementOrClass', + linterParams: ['example'], + marker: 'key', + markerTarget: 'examples', + target: 'examples', + data: {}, + targetSpecs: OpenAPI2, +}; + +export default examplesTypeLint; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/headers--type.ts b/packages/apidom-ls/src/config/openapi/response/lint/headers--type.ts new file mode 100644 index 000000000..22ab82c77 --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/response/lint/headers--type.ts @@ -0,0 +1,21 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI2 } from '../../target-specs'; + +const headersTypeLint: LinterMeta = { + code: ApilintCodes.OPENAPI2_RESPONSE_FIELD_HEADERS_TYPE, + source: 'apilint', + message: '"headers" must be an object', + severity: DiagnosticSeverity.Error, + linterFunction: 'apilintElementOrClass', + linterParams: ['headers'], + marker: 'key', + markerTarget: 'headers', + target: 'headers', + data: {}, + targetSpecs: OpenAPI2, +}; + +export default headersTypeLint; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/index.ts b/packages/apidom-ls/src/config/openapi/response/lint/index.ts index 6941082d0..6c630acde 100644 --- a/packages/apidom-ls/src/config/openapi/response/lint/index.ts +++ b/packages/apidom-ls/src/config/openapi/response/lint/index.ts @@ -1,17 +1,25 @@ +import allowedFields2_0Lint from './allowed-fields-2-0'; import allowedFields3_0Lint from './allowed-fields-3-0'; import allowedFields3_1Lint from './allowed-fields-3-1'; import descriptionTypeLint from './description--type'; import descriptionRequiredLint from './description--required'; import headersValuesTypeLint from './headers--values-type'; +import headersTypeLint from './headers--type'; import contentValuesTypeLint from './content--values-type'; import linksValuesTypeLint from './links--values-type'; +import schemaTypeLint from './schema--type'; +import examplesTypeLint from './examples--type'; const lints = [ descriptionTypeLint, descriptionRequiredLint, + headersTypeLint, headersValuesTypeLint, contentValuesTypeLint, linksValuesTypeLint, + schemaTypeLint, + examplesTypeLint, + allowedFields2_0Lint, allowedFields3_0Lint, allowedFields3_1Lint, ]; diff --git a/packages/apidom-ls/src/config/openapi/response/lint/schema--type.ts b/packages/apidom-ls/src/config/openapi/response/lint/schema--type.ts new file mode 100644 index 000000000..cf62de2e0 --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/response/lint/schema--type.ts @@ -0,0 +1,20 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI2 } from '../../target-specs'; + +const schemaTypeLint: LinterMeta = { + code: ApilintCodes.OPENAPI2_RESPONSE_FIELD_SCHEMA_TYPE, + source: 'apilint', + message: 'schema must be an object', + severity: DiagnosticSeverity.Error, + linterFunction: 'apilintElementOrClass', + linterParams: ['schema'], + marker: 'value', + target: 'schema', + data: {}, + targetSpecs: OpenAPI2, +}; + +export default schemaTypeLint; diff --git a/packages/apidom-ls/test/ads.ts b/packages/apidom-ls/test/ads.ts index d39513e63..68a51723f 100644 --- a/packages/apidom-ls/test/ads.ts +++ b/packages/apidom-ls/test/ads.ts @@ -120,7 +120,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ @@ -140,7 +140,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ @@ -160,7 +160,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ @@ -180,7 +180,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ @@ -200,7 +200,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ @@ -220,7 +220,7 @@ describe('apidom-ls-ads-validation-provider', function () { }, message: "should always have a 'description'", severity: 1, - code: 5290101, + code: 3120101, source: 'apilint', data: { quickFix: [ 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 c3ec80bfb..464a6c9db 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 @@ -8,10 +8,7 @@ parameters: in: path required: true type: string - schema: - type: string - format: uuid - title: Test Id + format: uuid paths: /foo/{bar_id}: delete: @@ -20,23 +17,15 @@ paths: responses: '200': description: Successful Response - content: - application/json: - schema: {} parameters: - name: foo_id in: path required: true type: string - schema: - type: string - format: uuid - title: Foo Id + format: uuid - name: bar_id in: path required: true type: string - schema: - type: string - format: uuid - title: Foo Id + format: uuid + diff --git a/packages/apidom-ls/test/fixtures/validation/oas/path-template-all-defined-2-0.yaml b/packages/apidom-ls/test/fixtures/validation/oas/path-template-all-defined-2-0.yaml index 6ad8de281..33b3d2d32 100644 --- a/packages/apidom-ls/test/fixtures/validation/oas/path-template-all-defined-2-0.yaml +++ b/packages/apidom-ls/test/fixtures/validation/oas/path-template-all-defined-2-0.yaml @@ -28,9 +28,6 @@ paths: responses: '200': description: Successful Response - content: - application/json: - schema: {} /test/{foo_id}/{bar_id}: get: summary: Get test foo bar @@ -44,9 +41,6 @@ paths: responses: '200': description: Successful Response - content: - application/json: - schema: {} /reference/{test_id}/{baz_id}: get: summary: Get test baz @@ -56,9 +50,6 @@ paths: responses: '200': description: Successful Response - content: - application/json: - schema: {} /just_parameters_object/{x_id}/{y_id}: parameters: - name: x_id @@ -79,9 +70,6 @@ paths: responses: '200': description: Successful Response - content: - application/json: - schema: {} parameters: - name: a_id in: path diff --git a/packages/apidom-ls/test/validate.ts b/packages/apidom-ls/test/validate.ts index 821fdb5b5..aee25453c 100644 --- a/packages/apidom-ls/test/validate.ts +++ b/packages/apidom-ls/test/validate.ts @@ -2887,7 +2887,7 @@ describe('apidom-ls-validate', function () { source: 'apilint', }, { - code: 5290101, + code: 3120101, data: { quickFix: [ { @@ -3410,21 +3410,21 @@ describe('apidom-ls-validate', function () { source: 'apilint', }, { - range: { start: { line: 33, character: 2 }, end: { line: 33, character: 25 } }, + range: { start: { line: 30, character: 2 }, end: { line: 30, character: 25 } }, message: 'path template expressions is not matched with Parameter Object(s)', severity: 1, code: 3040101, source: 'apilint', }, { - range: { start: { line: 61, character: 2 }, end: { line: 61, character: 39 } }, + range: { start: { line: 52, character: 2 }, end: { line: 52, character: 39 } }, message: 'path template expressions is not matched with Parameter Object(s)', severity: 1, code: 3040101, source: 'apilint', }, { - range: { start: { line: 68, character: 2 }, end: { line: 68, character: 61 } }, + range: { start: { line: 59, character: 2 }, end: { line: 59, character: 61 } }, message: 'path template expressions is not matched with Parameter Object(s)', severity: 1, code: 3040101, @@ -3580,7 +3580,7 @@ describe('apidom-ls-validate', function () { const result = await languageService.doValidation(doc, validationContext); const expected: Diagnostic[] = [ { - range: { start: { line: 26, character: 8 }, end: { line: 33, character: 23 } }, + range: { start: { line: 20, character: 8 }, end: { line: 24, character: 20 } }, message: 'parameter is not defined within path template', severity: 1, code: 3102000,