Skip to content

Commit

Permalink
feat(ls): add rules for OpenAPI 2.0 XML Object (#3666)
Browse files Browse the repository at this point in the history
Refs #3614
  • Loading branch information
char0n authored Jan 12, 2024
1 parent 8eb948a commit 1f539a3
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 30 deletions.
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;

0 comments on commit 1f539a3

Please sign in to comment.