Skip to content

Conversation

@robert-hebel-sb
Copy link
Contributor

Add AsyncAPI 3.0 Documentation and Configuration Support

Summary

This PR adds comprehensive documentation and configuration support for AsyncAPI 3.0 specification in the language server (apidom-ls). It builds upon the work done in PR #5095 by completing the documentation coverage for all AsyncAPI 3.0 objects and properties.

What Changed

1. New AsyncAPI 3.0 Configuration Directories

Added complete configuration structure for 5 new AsyncAPI 3.0-specific objects:

  • messages/ - Messages Object configuration
  • operations/ - Operations Object configuration
  • operation-reply/ - Operation Reply Object configuration
  • operation-reply-address/ - Operation Reply Address Object configuration
  • multi-format-schema/ - Multi Format Schema Object configuration

Each directory includes:

  • documentation.ts - Hover documentation with links to AsyncAPI 3.0 spec
  • completion.ts - Empty completion arrays (reserved for future use)
  • lint/index.ts - Linting configuration structure
  • meta.ts - Metadata configuration
  • All registered in config.ts

2. AsyncAPI 3.0 Support for Channel Item

Enhanced channel-item/ configuration with AsyncAPI 3.0 properties:

New Properties Documented:

  • address - String representation of the channel's address
  • messages - Map of messages sent to this channel
  • title - Human-readable title
  • summary - Short summary
  • tags - List of tags
  • externalDocs - External documentation
  • servers - Servers this channel is available on
  • parameters - Parameters in the channel address
  • bindings - Protocol-specific bindings

New Lint Rules:

  • allowed-fields-3-0.ts - Validates allowed fields for AsyncAPI 3.0
  • address--type.ts - Type validation for address
  • messages--type.ts - Type validation for messages
  • title--type.ts - Type validation for title
  • summary--type.ts - Type validation for summary
  • tags--type.ts - Type validation for tags
  • external-docs--type.ts - Type validation for externalDocs

3. Completed Missing Documentation

Added missing documentation for several AsyncAPI objects:

asyncapi3/documentation.ts

  • Added comprehensive AsyncAPI Object documentation with all fixed fields (asyncapi, id, info, servers, defaultContentType, channels, operations, components)

operation/documentation.ts

  • Added missing required channel property documentation

components/documentation.ts

  • Added missing operations property documentation

security-requirement/documentation.ts

  • Added AsyncAPI 3.0-specific variant with updated role names support

4. JSON Schema Support for AsyncAPI 3.0

Updated common/schema/documentation.ts to extend all JSON Schema keywords for AsyncAPI 3.0:

Updated 46 JSON Schema keywords to support AsyncAPI 3.0:

  • Type validation: type, enum, const
  • Numeric validation: multipleOf, maximum, minimum, exclusiveMaximum, exclusiveMinimum
  • String validation: maxLength, minLength, pattern
  • Array validation: items, additionalItems, maxItems, minItems, uniqueItems, contains
  • Object validation: maxProperties, minProperties, required, properties, patternProperties, additionalProperties, dependencies, propertyNames
  • Conditional: if, then, else
  • Boolean logic: allOf, anyOf, oneOf, not
  • Reference: $ref
  • Metadata: title, description, examples, deprecated

AsyncAPI-specific Schema Properties:

  • default - Added AsyncAPI 3.0 support (value must conform to defined type)
  • discriminator - Added separate AsyncAPI 3.0 entry with updated spec links
  • externalDocs - Added separate AsyncAPI 3.0 entry with updated spec links

5. Documentation

Added CLAUDE.md to help future Claude Code instances understand the repository structure and development workflow.

Key Technical Details

AsyncAPI 2.0 vs 3.0 Major Differences

  • Channels: In v2, channels had subscribe/publish; in v3, they have messages + address
  • Operations: Moved from channel-level to top-level with action, channel, and reply properties
  • Server: Changed from url to host + pathname; added title, summary, externalDocs
  • Messages: Added MultiFormatSchema support
  • Components: Added operations, replies, and replyAddresses

Documentation Pattern

All documentation entries follow this pattern:

{
  target: 'propertyName',  // or docs for object-level documentation
  docs: '#### [Object Name](spec-url)...',  // Markdown with spec links
  targetSpecs: AsyncAPI3,  // or [...AsyncAPI2, ...AsyncAPI3] for shared docs
}

Completion Pattern

All completion files are currently empty arrays:

const completion: ApidomCompletionItem[] = [];
export default completion;

Files Changed

  • 36 files changed: 633 insertions(+), 48 deletions(-)
  • New directories: 5 configuration directories for AsyncAPI 3.0 objects
  • New files: 31 new configuration and documentation files
  • Updated files: 5 existing documentation files enhanced with AsyncAPI 3.0 support

References

ShikhaSaboo and others added 12 commits January 12, 2026 17:19
This commit completes AsyncAPI 3 documentation support by updating:
- asyncapi3/documentation.ts: Added comprehensive AsyncAPI Object documentation
- components/documentation.ts: Added missing operations property
- operation/documentation.ts: Added required channel property
- security-requirement/documentation.ts: Added AsyncAPI 3 variant with role names support
- common/schema/documentation.ts: Extended all JSON Schema keywords to support AsyncAPI 3

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@robert-hebel-sb robert-hebel-sb changed the title Feat/oss 245 docs on hover for async3 new keywords feat: add documentation support for async3 new keywords Jan 20, 2026
@robert-hebel-sb robert-hebel-sb added enhancement New feature or request AsyncAPI 3.x labels Jan 20, 2026
@robert-hebel-sb robert-hebel-sb changed the title feat: add documentation support for async3 new keywords feat(ls): add AsyncAPI 3 completion for new keywords Jan 20, 2026
@robert-hebel-sb robert-hebel-sb changed the title feat(ls): add AsyncAPI 3 completion for new keywords feat(ls): add AsyncAPI 3 documentation for new keywords Jan 20, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

docs: '#### [Channel Item Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#channelItemObject)\n\nDescribes the operations available on a single channel.\n\n##### Fixed Fields\n\nField Name | Type | Description\n---|:---:|---\n$ref | `string` | Allows for an external definition of this channel item. The referenced structure MUST be in the format of a [Channel Item Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#channelItemObject). If there are conflicts between the referenced definition and this Channel Item\'s definition, the behavior is *undefined*. **Deprecated:** Usage of the `$ref` property has been deprecated.\ndescription | `string` | An optional description of this channel item. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation.\nservers | [`string`] | The servers on which this channel is available, specified as an optional unordered list of names (string keys) of [Server Objects](https://www.asyncapi.com/docs/reference/specification/v2.6.0#serverObject) defined in the [Servers Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#serversObject) (a map). If `servers` is absent or empty then this channel must be available on all servers defined in the [Servers Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#serversObject).\nsubscribe | [Operation Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#operationObject) | A definition of the SUBSCRIBE operation, which defines the messages produced by the application and sent to the channel.\npublish | [Operation Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#operationObject) | A definition of the PUBLISH operation, which defines the messages consumed by the application from the channel.\nparameters | [Parameters Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#parametersObject) | A map of the parameters included in the channel name. It SHOULD be present only when using channels with expressions (as defined by [RFC 6570 section 2.2](https://tools.ietf.org/html/rfc6570#section-2.2)).\nbindings | [Channel Bindings Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#channelBindingsObject) \\| [Reference Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the channel.\n\nThis object MAY be extended with [Specification Extensions](https://www.asyncapi.com/docs/reference/specification/v2.6.0#specificationExtensions).\n\n##### Channel Item Object Example\n\n\n\\\nJSON\n```json\n{\n "description": "This channel is used to exchange messages about users signing up",\n "subscribe": {\n "summary": "A user signed up.",\n "message": {\n "description": "A longer description of the message",\n "payload": {\n "type": "object",\n "properties": {\n "user": {\n "$ref": "#/components/schemas/user"\n },\n "signup": {\n "$ref": "#/components/schemas/signup"\n }\n }\n }\n }\n },\n "bindings": {\n "amqp": {\n "is": "queue",\n "queue": {\n "exclusive": true\n }\n }\n }\n}\n```\n\n\n\\\nYAML\n```yaml\ndescription: This channel is used to exchange messages about users signing up\nsubscribe:\n summary: A user signed up.\n message:\n description: A longer description of the message\n payload:\n type: object\n properties:\n user:\n $ref: "#/components/schemas/user"\n signup:\nbindings:\n amqp:\n is: queue\n queue:\n exclusive: true\n```\n\nUsing `oneOf` to specify multiple messages per operation:\n\n```json\n{\n "subscribe": {\n "message": {\n "oneOf": [\n { "$ref": "#/components/messages/signup" },\n { "$ref": "#/components/messages/login" }\n ]\n }\n }\n}\n```\n\n```yaml\nsubscribe:\n message:\n oneOf:\n - $ref: \'#/components/messages/signup\'\n - $ref: \'#/components/messages/login\'\n```\n\n\nUsing explicit by-name references to the servers on which the channel is available:\n\n```json\n{\n "description": "This application publishes WebUICommand messages to an AMQP queue on RabbitMQ brokers in the Staging and Production environments.",\n "servers": [\n "rabbitmqBrokerInProd",\n "rabbitmqBrokerInStaging",\n ],\n "subscribe": {\n "message": {\n "$ref": "#/components/messages/WebUICommand"\n }\n },\n "bindings": {\n "amqp": {\n "is": "queue"\n }\n }\n}\n```\n\n```yaml\ndescription: This application publishes WebUICommand messages to an AMQP queue on RabbitMQ brokers in the Staging and Production environments.\nservers:\n - rabbitmqBrokerInProd\n - rabbitmqBrokerInStaging\nsubscribe:\n message:\n $ref: "#/components/messages/WebUICommand"\nbindings:\n amqp:\n is: queue\n```',
targetSpecs: AsyncAPI2,
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rules for AsyncAPI 3 should be moved to channel folder, as Channel Item Object was renamed to Channel Object and the element is also named channel now, so these rules would probably not apply to it.

targetSpecs: AsyncAPI3,
},
{
docs: '#### [Channel Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelObject)\n\nDescribes a shared communication channel.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it also needs to have the description for the different fields, like in Async 2.


const documentation = [
{
docs: '#### [Messages Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#messagesObject)\n\nDescribes a map of messages which are used for sending and receiving messages. The map key represents the messageId and the map value is the definition of that message.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should also have fields + their descriptions, e.g. as for Channels Object

The description in the spec is also simply:

Describes a map of messages included in a channel.


const documentation = [
{
docs: '#### [Multi Format Schema Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaObject)\n\nThe Multi Format Schema Object represents a schema definition. It differs from the [Schema Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#schemaObject) in that it supports multiple schema formats or languages (e.g., JSON Schema, Avro, etc.).',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also probably should have the description for the fields.


const documentation = [
{
docs: '#### [Operation Reply Address Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationReplyAddressObject)\n\nAn object that specifies where an operation has to send the reply.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the others, probably needs to have the fields descriptions.

Also missing this at the end?

For specifying and computing the location of a reply address, a runtime expression is used.

},
{
target: 'schemaFormat',
docs: 'A string containing the name of the schema format that is used to define the message payload. If omitted, implementations should parse the payload as a [Schema Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#schemaObject). When the payload is defined using a $ref to a remote file, it is RECOMMENDED the schema format includes the file encoding type to allow implementations to parse the file correctly. E.g., adding +yaml if content type is application/vnd.apache.avro results in application/vnd.apache.avro+yaml.\\\n\\\nCheck out the [supported schema formats table](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaFormatTable) for more information. Custom values are allowed but their implementation is OPTIONAL. A custom value MUST NOT refer to one of the schema formats listed in the [table](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaFormatTable).\\\n\\\nWhen using [Reference Objects](https://www.asyncapi.com/docs/reference/specification/v3.0.0#referenceObject) within the schema, the schemaFormat of the resource being referenced MUST match the schemaFormat of the schema that contains the initial reference. For example, if you reference Avro schema, then schemaFormat of referencing resource and the resource being referenced MUST match.\\\n\\\n**Note:** This field is optional, but despite this, for clarity and explicitness, we recommend that you always use it to specify the schema format. For AsyncAPI v2.x documents, the default value is `application/vnd.aai.asyncapi;version=2.x.0`, while for AsyncAPI v3.0.0 documents, the default value is `application/vnd.aai.asyncapi+json;version=3.0.0` or `application/vnd.aai.asyncapi+yaml;version=3.0.0`, depending on the protocol of the given document.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required info. The description also seems to be at least a bit different, the start for example:

Required. A string containing the name of the schema format that is used to define the information. If schemaFormat is missing, it MUST default to application/vnd.aai.asyncapi+json;version={{asyncapi}} where {{asyncapi}} matches the AsyncAPI Version String. In such a case, this would make the Multi Format Schema Object equivalent to the Schema Object.

},
{
target: 'schema',
docs: 'Definition of the message payload. It can be of any type but defaults to [Schema Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#schemaObject). It MUST match the schema format defined in [schemaFormat](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaObjectSchemaFormat), including the encoding type. E.g., Avro should be inlined as either a YAML or JSON object instead of as a string to be parsed as YAML or JSON. Non-JSON-based schemas (e.g., Protobuf or XSD) MUST be inlined as a string.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required info.

},
{
target: 'address',
docs: 'An optional string representation of this channel\'s address. The address is typically the "topic name", "routing key", "event type", or "path". When `null` or absent, it MUST be interpreted as unknown. This is useful when the address is generated dynamically at runtime or can\'t be known upfront. It MAY contain [Channel Address Expressions](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelAddressExpressions).',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing at the end:

Query parameters and fragments SHALL NOT be used, instead use bindings to define them.

},
{
target: 'servers',
docs: '[[Reference Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#referenceObject)]\n\\\n\\\nAn array of $ref pointers to the definition of the servers in which this channel is available. If the channel is located in the [root Channels Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelsObject), it MUST point to a subset of server definitions located in the [root Servers Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serversObject), and MUST NOT point to a subset of server definitions located in the [Components Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#componentsObject) or anywhere else. If the channel is located in the [Components Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#componentsObject), it MAY point to a [Server Objects](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serverObject) in any location. If `servers` is absent or empty, this channel MUST be available on all the servers defined in the [Servers Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serversObject).',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing at the end:

Please note the servers property value MUST be an array of Reference Objects and, therefore, MUST NOT contain an array of Server Objects. However, it is RECOMMENDED that parsers (or other software) dereference this property for a better development experience.

const documentation = [
{
docs: '', // Add all the allowed fields link here.
docs: "#### [AsyncAPI Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#A2SObject)\n\nThis is the root object of the [AsyncAPI document](https://www.asyncapi.com/docs/reference/specification/v3.0.0#definitionsAsyncAPIDocument).\n\n##### Fixed Fields\n\nField Name | Type | Description\n---|:---:|---\nasyncapi | [AsyncAPI Version String](https://www.asyncapi.com/docs/reference/specification/v3.0.0#A2SVersionString) | **REQUIRED**. Specifies the AsyncAPI Specification version being used. It can be used by tooling Specifications and clients to interpret the version. The structure shall be `major`.`minor`.`patch`, where `patch` versions _must_ be compatible with the existing `major`.`minor` tooling. Typically patch versions will be introduced to address errors in the documentation, and tooling should typically be compatible with the corresponding `major`.`minor` (1.0.*). Patch versions will correspond to patches of this document.\nid | [Identifier](https://www.asyncapi.com/docs/reference/specification/v3.0.0#A2SIdString) | Identifier of the [application](https://www.asyncapi.com/docs/reference/specification/v3.0.0#definitionsApplication) the AsyncAPI document is defining.\ninfo | [Info Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#infoObject) | **REQUIRED**. Provides metadata about the API. The metadata can be used by the clients if needed.\nservers | [Servers Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serversObject) | Provides connection details of servers.\ndefaultContentType | [Default Content Type](https://www.asyncapi.com/docs/reference/specification/v3.0.0#defaultContentTypeString) | Default content type to use when encoding/decoding a message's payload.\nchannels | [Channels Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelsObject) | The channels used by this [application](https://www.asyncapi.com/docs/reference/specification/v3.0.0#definitionsApplication).\noperations | [Operations Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationsObject) | The operations this [application](https://www.asyncapi.com/docs/reference/specification/v3.0.0#definitionsApplication) MUST implement.\ncomponents | [Components Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#componentsObject) | An element to hold various reusable objects for the specification. Everything that is defined inside this object represents a resource that MAY or MAY NOT be used in the rest of the document and MAY or MAY NOT be used by the implemented [Application](https://www.asyncapi.com/docs/reference/specification/v3.0.0#definitionsApplication).",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least the object description is different:

This is the root document object for the API specification. It combines resource listing and API declaration together into one document.

robert-hebel-sb and others added 2 commits January 22, 2026 10:33
…-compatible-properties' into feat/oss-245-docs-on-hover-for-async3-new-keywords

# Conflicts:
#	packages/apidom-ls/src/config/common/schema/documentation.ts
- Create separate channel config for AsyncAPI 3 (Channel Object vs Channel Item Object)
- Move AsyncAPI 3 rules from channel-item to new channel folder
- Add field description tables to all AsyncAPI 3 object documentation
- Mark required fields explicitly with REQUIRED prefix in documentation
- Add Reference Object notes where specification requires them
- Add runtime expression note to Operation Reply Address
- Remove invalid AsyncAPI 3 Security Requirement Object documentation
- Update AsyncAPI 3 root object description to match specification
- Update lint rules for Channel Object to use Reference Objects for servers

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 48 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,27 @@
import allowedFields3_0Lint from './allowed-fields-3-0.ts';
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import name allowedFields3_0Lint uses an underscore in the version number (3_0) which is inconsistent with the file naming convention that uses hyphens (allowed-fields-3-0.ts). Consider renaming to allowedFields3Hyphen0Lint or allowedFieldsV3Lint for consistency, or adjust the file name to use underscores.

Copilot uses AI. Check for mistakes.
const documentation = [
{
target: 'address',
docs: 'An optional string representation of this channel\'s address. The address is typically the "topic name", "routing key", "event type", or "path". When `null` or absent, it MUST be interpreted as unknown. This is useful when the address is generated dynamically at runtime or can\'t be known upfront. It MAY contain [Channel Address Expressions](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelAddressExpressions).\n\\\n\\\nQuery parameters and fragments SHALL NOT be used, instead use [bindings](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelBindingsObject) to define them.',
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation string uses \n\\\n\\\n for line breaks which appears to be an unusual escaping pattern. Consider verifying if this is the intended formatting or if it should use standard markdown line breaks.

Copilot uses AI. Check for mistakes.
@robert-hebel-sb robert-hebel-sb marked this pull request as draft January 22, 2026 10:11
robert-hebel-sb and others added 2 commits January 22, 2026 11:16
- Move individual field entries before object-level docs in multi-format-schema
- Move individual field entries before object-level docs in operation-reply
- This ensures field-specific hover documentation displays correctly
- Operations documentation already follows correct pattern with patterned fields

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@robert-hebel-sb robert-hebel-sb marked this pull request as ready for review January 22, 2026 11:00
Base automatically changed from feat/OSS-254/251-add-config-and-docs-for-asyncapi3-with-compatible-properties to main January 23, 2026 07:34
…ywords

# Conflicts:
#	packages/apidom-ls/src/config/asyncapi/asyncapi3/documentation.ts
#	packages/apidom-ls/src/config/asyncapi/components/documentation.ts
#	packages/apidom-ls/src/config/asyncapi/operation/documentation.ts
#	packages/apidom-ls/src/config/common/schema/documentation.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AsyncAPI 3.x enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants