From 8b23074ccd717c8063a27ab8c7140f48a176d5d2 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Tue, 10 May 2022 16:47:41 +0200 Subject: [PATCH] feat(apidom-ls): support referencing Server Object Closes #1431 --- .../src/config/asyncapi/server/completion.ts | 12 ++++++++ .../config/asyncapi/server/documentation.ts | 4 +++ .../src/config/asyncapi/server/lint/index.ts | 4 +++ .../asyncapi/server/lint/ref-non-siblings.ts | 30 +++++++++++++++++++ .../src/config/asyncapi/server/lint/ref.ts | 15 ++++++++++ packages/apidom-ls/src/config/codes.ts | 2 ++ 6 files changed, 67 insertions(+) create mode 100644 packages/apidom-ls/src/config/asyncapi/server/lint/ref-non-siblings.ts create mode 100644 packages/apidom-ls/src/config/asyncapi/server/lint/ref.ts diff --git a/packages/apidom-ls/src/config/asyncapi/server/completion.ts b/packages/apidom-ls/src/config/asyncapi/server/completion.ts index d3049e7238..fa1704a6ad 100644 --- a/packages/apidom-ls/src/config/asyncapi/server/completion.ts +++ b/packages/apidom-ls/src/config/asyncapi/server/completion.ts @@ -356,6 +356,18 @@ const completion: ApidomCompletionItem[] = [ function: 'apicompleteSecurity', insertTextFormat: 2, }, + { + label: '$ref', + insertText: '\\$ref', + kind: 14, + format: CompletionFormat.QUOTED, + type: CompletionType.PROPERTY, + insertTextFormat: 2, + documentation: { + kind: 'markdown', + value: 'A reference to a server', + }, + }, ]; export default completion; diff --git a/packages/apidom-ls/src/config/asyncapi/server/documentation.ts b/packages/apidom-ls/src/config/asyncapi/server/documentation.ts index 87f82a67b6..f2c3ef521b 100644 --- a/packages/apidom-ls/src/config/asyncapi/server/documentation.ts +++ b/packages/apidom-ls/src/config/asyncapi/server/documentation.ts @@ -27,6 +27,10 @@ const documentation = [ target: 'bindings', docs: '[Server Bindings Object](https://www.asyncapi.com/docs/specifications/v2.4.0#serverBindingsObject) \\| [Reference Object](https://www.asyncapi.com/docs/specifications/v2.4.0#referenceObject)\n\\\n\\\nA map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the server.', }, + { + target: '$ref', + docs: 'A reference to a server.', + }, { docs: '#### [Server Object](https://www.asyncapi.com/docs/specifications/v2.4.0#serverObject)\n\nAn object representing a message broker, a server or any other kind of computer program capable of sending and/or receiving data. This object is used to capture details such as URIs, protocols and security configuration. Variable substitution can be used so that some details, for example usernames and passwords, can be injected by code generation tools.\n\n##### Fixed Fields\n\nField Name | Type | Description\n---|:---:|---\nurl | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the AsyncAPI document is being served. Variable substitutions will be made when a variable is named in `{`braces`}`.\nprotocol | `string` | **REQUIRED**. The protocol this URL supports for connection. Supported protocol include, but are not limited to: `amqp`, `amqps`, `http`, `https`, `ibmmq`, `jms`, `kafka`, `kafka-secure`, `anypointmq`, `mqtt`, `secure-mqtt`, `solace`, `stomp`, `stomps`, `ws`, `wss`, `mercure`.\nprotocolVersion | `string` | The version of the protocol used for connection. For instance: AMQP `0.9.1`, HTTP `2.0`, Kafka `1.0.0`, etc.\ndescription | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.\nvariables | Map[`string`, [Server Variable Object](https://www.asyncapi.com/docs/specifications/v2.4.0#serverVariableObject)] | A map between a variable name and its value. The value is used for substitution in the server\'s URL template.\nsecurity | [[Security Requirement Object](https://www.asyncapi.com/docs/specifications/v2.4.0#securityRequirementObject)] | A declaration of which security mechanisms can be used with this server. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a connection or operation.\nbindings | [Server Bindings Object](https://www.asyncapi.com/docs/specifications/v2.4.0#serverBindingsObject) \\| [Reference Object](https://www.asyncapi.com/docs/specifications/v2.4.0#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the server.\n\nThis object MAY be extended with [Specification Extensions](https://www.asyncapi.com/docs/specifications/v2.4.0#specificationExtensions).\n\n##### Server Object Example\n\nA single server would be described as:\n\n\n\\\nJSON\n```json\n{\n "url": "development.gigantic-server.com",\n "description": "Development server",\n "protocol": "kafka",\n "protocolVersion": "1.0.0"\n}\n```\n\n\n\\\nYAML\n```yaml\nurl: development.gigantic-server.com\ndescription: Development server\nprotocol: kafka\nprotocolVersion: \'1.0.0\'\n```', }, diff --git a/packages/apidom-ls/src/config/asyncapi/server/lint/index.ts b/packages/apidom-ls/src/config/asyncapi/server/lint/index.ts index 8b1da9bb18..ba1e067e1f 100644 --- a/packages/apidom-ls/src/config/asyncapi/server/lint/index.ts +++ b/packages/apidom-ls/src/config/asyncapi/server/lint/index.ts @@ -9,6 +9,8 @@ import serverVariablesObjectLint from './variables-object'; import serverSecurityLint from './security'; import serverBindingsObjectLint from './bindings'; import serverAllowedFieldsLint from './allowed-fields'; +import serverRefNonSiblingsLint from './ref-non-siblings'; +import server$RefLint from './ref'; const lints = [ serverUrlLint, @@ -22,6 +24,8 @@ const lints = [ serverSecurityLint, serverBindingsObjectLint, serverAllowedFieldsLint, + serverRefNonSiblingsLint, + server$RefLint, ]; export default lints; diff --git a/packages/apidom-ls/src/config/asyncapi/server/lint/ref-non-siblings.ts b/packages/apidom-ls/src/config/asyncapi/server/lint/ref-non-siblings.ts new file mode 100644 index 0000000000..294897f096 --- /dev/null +++ b/packages/apidom-ls/src/config/asyncapi/server/lint/ref-non-siblings.ts @@ -0,0 +1,30 @@ +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; + +const serverRefNonSiblingsLint: LinterMeta = { + code: ApilintCodes.SERVER_REF_SIBLINGS, + source: 'apilint', + message: 'All other properties in a "$ref" object are ignored', + severity: 2, + linterFunction: 'allowedFields', + linterParams: [['$ref']], + marker: 'key', + conditions: [ + { + function: 'existFields', + params: [['$ref']], + }, + ], + data: { + quickFix: [ + { + message: 'remove $ref', + action: 'removeChild', + functionParams: ['$ref'], + target: 'parent', + }, + ], + }, +}; + +export default serverRefNonSiblingsLint; diff --git a/packages/apidom-ls/src/config/asyncapi/server/lint/ref.ts b/packages/apidom-ls/src/config/asyncapi/server/lint/ref.ts new file mode 100644 index 0000000000..077e0aae61 --- /dev/null +++ b/packages/apidom-ls/src/config/asyncapi/server/lint/ref.ts @@ -0,0 +1,15 @@ +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; + +const server$RefLint: LinterMeta = { + code: ApilintCodes.SERVER_REF, + source: 'apilint', + message: "'$ref' value must be a valid URI-reference", + severity: 1, + linterFunction: 'apilintValidURI', + marker: 'value', + target: '$ref', + data: {}, +}; + +export default server$RefLint; diff --git a/packages/apidom-ls/src/config/codes.ts b/packages/apidom-ls/src/config/codes.ts index 04a0c058bc..4171cf6b04 100644 --- a/packages/apidom-ls/src/config/codes.ts +++ b/packages/apidom-ls/src/config/codes.ts @@ -261,6 +261,8 @@ enum ApilintCodes { ASYNCAPI_ASYNCAPIVERSION_2_4, COMPONENTS_SERVERS, COMPONENTS_SERVER_VARIABLES, + SERVER_REF, + SERVER_REF_SIBLINGS, } export default ApilintCodes;