Skip to content
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(ls): add rules for OpenAPI 2.0 XML Object #3666

Merged
merged 1 commit into from
Jan 12, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/apidom-ls/src/config/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,13 @@ enum ApilintCodes {
OPENAPI2_TAG_FIELD_DESCRIPTION_TYPE = 3190200,
OPENAPI2_TAG_FIELD_EXTERNAL_DOCS_TYPE = 3190300,

OPENAPI2_XML = 3200000,
OPENAPI2_XML_FIELD_NAME_TYPE = 3200100,
OPENAPI2_XML_FIELD_NAMESPACE_FORMAT_URI = 3200200,
OPENAPI2_XML_FIELD_PREFIX_TYPE = 3200300,
OPENAPI2_XML_FIELD_ATTRIBUTE_TYPE = 3200400,
OPENAPI2_XML_FIELD_WRAPPED_TYPE = 3200500,

OPENAPI3_0 = 5000000,

OPENAPI3_0_OPENAPI_VALUE_PATTERN_3_0_0 = 5000100,
Expand Down
47 changes: 44 additions & 3 deletions packages/apidom-ls/src/config/openapi/xml/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@ 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[] = [
{
label: 'name',
insertText: 'name',
kind: 14,
format: CompletionFormat.QUOTED,
type: CompletionType.PROPERTY,
insertTextFormat: 2,
documentation: {
kind: 'markdown',
value:
'Replaces the name of the element/attribute used for the described schema property. When defined within the Items Object (`items`), it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.',
},
targetSpecs: OpenAPI2,
},
{
label: 'name',
insertText: 'name',
Expand All @@ -20,6 +34,19 @@ const completion: ApidomCompletionItem[] = [
},
targetSpecs: OpenAPI3,
},
{
label: 'namespace',
insertText: 'namespace',
kind: 14,
format: CompletionFormat.QUOTED,
type: CompletionType.PROPERTY,
insertTextFormat: 2,
documentation: {
kind: 'markdown',
value: 'The URL of the namespace definition. Value SHOULD be in the form of a URL.',
},
targetSpecs: OpenAPI2,
},
{
label: 'namespace',
insertText: 'namespace',
Expand All @@ -33,6 +60,20 @@ const completion: ApidomCompletionItem[] = [
},
targetSpecs: OpenAPI3,
},
{
label: 'prefix',
insertText: 'prefix ',
kind: 14,
format: CompletionFormat.QUOTED,
type: CompletionType.PROPERTY,
insertTextFormat: 2,
documentation: {
kind: 'markdown',
value:
'The prefix to be used for the [name](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xmlName).',
},
targetSpecs: OpenAPI2,
},
{
label: 'prefix',
insertText: 'prefix ',
Expand Down Expand Up @@ -73,7 +114,7 @@ const completion: ApidomCompletionItem[] = [
value:
'Declares whether the property definition translates to an attribute instead of an element. Default value is `false`.',
},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
},
{
label: 'wrapped',
Expand All @@ -87,7 +128,7 @@ const completion: ApidomCompletionItem[] = [
value:
'MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`).',
},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
},
];

Expand Down
34 changes: 24 additions & 10 deletions packages/apidom-ls/src/config/openapi/xml/documentation.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import { OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs';
import { OpenAPI2, OpenAPI30, OpenAPI31, OpenAPI3 } from '../target-specs';

const documentation = [
{
target: 'name',
docs: 'Replaces the name of the element/attribute used for the described schema property. When defined within the Items Object (`items`), it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.',
targetSpecs: OpenAPI2,
},
{
target: 'name',
docs: 'Replaces the name of the element/attribute used for the described schema property. When defined within `items`, it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.',
targetSpecs: OpenAPI3,
},
{
target: 'namespace',
docs: 'The URL of the namespace definition. Value SHOULD be in the form of a URL.',
targetSpecs: OpenAPI2,
},
{
target: 'namespace',
docs: 'The URI of the namespace definition. This MUST be in the form of an absolute URI.',
targetSpecs: OpenAPI3,
},
{
target: 'prefix',
docs: 'The prefix to be used for the [name](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xmlName).',
targetSpecs: OpenAPI2,
},
{
target: 'prefix',
docs: 'The prefix to be used for the [name](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xmlName).',
Expand All @@ -24,30 +39,29 @@ const documentation = [
{
target: 'attribute',
docs: 'Declares whether the property definition translates to an attribute instead of an element. Default value is `false`.',
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
},
{
target: 'wrapped',
docs: 'MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`).',
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
},
/**
* The original documentation has been trimmed in this implementation for readability purposes
* A new custom section `Additional documentation topics` has been added,
* which adds external links back to the original documentation
*/
{
docs: '#### [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xmlObject)\n\nA metadata object that allows for more fine-tuned XML model definitions.\n\nWhen using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property should be used to add that information. See examples for expected behavior.\n\n##### Fixed Fields\nField Name | Type | Description\n---|:---:|---\nname | `string` | Replaces the name of the element/attribute used for the described schema property. When defined within the Items Object (`items`), it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.\nnamespace | `string` | The URL of the namespace definition. Value SHOULD be in the form of a URL.\nprefix | `string` | The prefix to be used for the [name](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xmlName).\nattribute | `boolean` | Declares whether the property definition translates to an attribute instead of an element. Default value is `false`.\nwrapped | `boolean` | MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`).\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#### Additional documentation topics\n\n##### [XML Object Examples](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xml-object-examples)\nThe examples of the XML object definitions are included inside a property definition of a [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#schemaObject) with a sample of the XML representation of it.\n\n- [No XML Element](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#no-xml-element)\n- [XML Name Replacement](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xml-name-replacement)\n- [https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xml-attribute-prefix-and-namespace)\n- [XML Arrays](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#xml-arrays)',
targetSpecs: OpenAPI2,
},
{
docs: '#### [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xmlObject)\n\nA metadata object that allows for more fine-tuned XML model definitions.\n\nWhen using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information.\nSee examples for expected behavior.\n\n##### Fixed Fields\nField Name | Type | Description\n---|:---:|---\nname | `string` | Replaces the name of the element/attribute used for the described schema property. When defined within `items`, it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.\nnamespace | `string` | The URI of the namespace definition. Value MUST be in the form of an absolute URI.\nprefix | `string` | The prefix to be used for the [name](#xmlName).\nattribute | `boolean` | Declares whether the property definition translates to an attribute instead of an element. Default value is `false`.\nwrapped | `boolean` | MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`).\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#### Additional documentation topics\n\n##### [XML Object Examples](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-object-examples)\nThe examples of the XML object definitions are included inside a property definition of a [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject) with a sample of the XML representation of it.\n\n- [No XML Element](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#no-xml-element)\n- [XML Name Replacement](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-name-replacement)\n- [XML Attribute, Prefix and Namespace](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-attribute-prefix-and-namespace)\n- [XML Arrays](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-arrays)',
targetSpecs: [
{ namespace: 'openapi', version: '3.0.0' },
{ namespace: 'openapi', version: '3.0.1' },
{ namespace: 'openapi', version: '3.0.2' },
{ namespace: 'openapi', version: '3.0.3' },
],
targetSpecs: OpenAPI30,
},
{
docs: '#### [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xmlObject)\n\nA metadata object that allows for more fine-tuned XML model definitions.\n\nWhen using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information.\nSee examples for expected behavior.\n\n##### Fixed Fields\nField Name | Type | Description\n---|:---:|---\nname | `string` | Replaces the name of the element/attribute used for the described schema property. When defined within `items`, it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored.\nnamespace | `string` | The URI of the namespace definition. This MUST be in the form of an absolute URI.\nprefix | `string` | The prefix to be used for the [name](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xmlName).\nattribute | `boolean` | Declares whether the property definition translates to an attribute instead of an element. Default value is `false`.\nwrapped | `boolean` | MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`).\n\nThis object MAY be extended with [Specification Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specificationExtensions).\n\n#### Additional documentation topics\n\n##### [XML Object Examples](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xml-object-examples)\nThe examples of the XML object definitions are included inside a property definition of a [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject) with a sample of the XML representation of it.\n\n- [No XML Element](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#no-xml-element)\n- [XML Name Replacement](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xml-name-replacement)\n- [XML Attribute, Prefix and Namespace](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xml-attribute-prefix-and-namespace)\n- [XML Arrays](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#xml-arrays)\n',
targetSpecs: [{ namespace: 'openapi', version: '3.1.0' }],
targetSpecs: OpenAPI31,
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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 allowedFieldsLint: LinterMeta = {
code: ApilintCodes.NOT_ALLOWED_FIELDS,
Expand All @@ -12,7 +12,7 @@ const allowedFieldsLint: LinterMeta = {
linterFunction: 'allowedFields',
linterParams: [['name', 'namespace', 'prefix', 'attribute', 'wrapped'], 'x-'],
marker: 'key',
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default allowedFieldsLint;
Original file line number Diff line number Diff line change
Expand Up @@ -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 attributeTypeLint: LinterMeta = {
code: ApilintCodes.OPENAPI3_0_XML_FIELD_ATTRIBUTE_TYPE,
code: ApilintCodes.OPENAPI2_XML_FIELD_ATTRIBUTE_TYPE,
source: 'apilint',
message: 'attribute must be a boolean',
severity: DiagnosticSeverity.Error,
Expand All @@ -14,7 +14,7 @@ const attributeTypeLint: LinterMeta = {
marker: 'value',
target: 'attribute',
data: {},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default attributeTypeLint;
6 changes: 3 additions & 3 deletions packages/apidom-ls/src/config/openapi/xml/lint/name--type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 nameTypeLint: LinterMeta = {
code: ApilintCodes.OPENAPI3_0_XML_FIELD_NAME_TYPE,
code: ApilintCodes.OPENAPI2_XML_FIELD_NAME_TYPE,
source: 'apilint',
message: 'name must be a string',
severity: DiagnosticSeverity.Error,
Expand All @@ -14,7 +14,7 @@ const nameTypeLint: LinterMeta = {
marker: 'value',
target: 'name',
data: {},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default nameTypeLint;
Original file line number Diff line number Diff line change
Expand Up @@ -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 namespaceFormatURILint: LinterMeta = {
code: ApilintCodes.OPENAPI3_0_XML_FIELD_NAMESPACE_FORMAT_URI,
code: ApilintCodes.OPENAPI2_XML_FIELD_NAMESPACE_FORMAT_URI,
source: 'apilint',
message: 'namespace MUST be in the format of an absolute URL.',
severity: DiagnosticSeverity.Error,
Expand All @@ -14,7 +14,7 @@ const namespaceFormatURILint: LinterMeta = {
marker: 'value',
target: 'namespace',
data: {},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default namespaceFormatURILint;
Original file line number Diff line number Diff line change
Expand Up @@ -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 prefixTypeLint: LinterMeta = {
code: ApilintCodes.OPENAPI3_0_XML_FIELD_PREFIX_TYPE,
code: ApilintCodes.OPENAPI2_XML_FIELD_PREFIX_TYPE,
source: 'apilint',
message: 'prefix must be a string',
severity: DiagnosticSeverity.Error,
Expand All @@ -14,7 +14,7 @@ const prefixTypeLint: LinterMeta = {
marker: 'value',
target: 'prefix',
data: {},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default prefixTypeLint;
Original file line number Diff line number Diff line change
Expand Up @@ -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 wrappedTypeLint: LinterMeta = {
code: ApilintCodes.OPENAPI3_0_XML_FIELD_WRAPPED_TYPE,
code: ApilintCodes.OPENAPI2_XML_FIELD_WRAPPED_TYPE,
source: 'apilint',
message: 'wrapped must be a boolean',
severity: DiagnosticSeverity.Error,
Expand All @@ -14,7 +14,7 @@ const wrappedTypeLint: LinterMeta = {
marker: 'value',
target: 'wrapped',
data: {},
targetSpecs: OpenAPI3,
targetSpecs: [...OpenAPI2, ...OpenAPI3],
};

export default wrappedTypeLint;