diff --git a/package-lock.json b/package-lock.json
index 7157c91b06..602b8f51b5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6936,6 +6936,10 @@
"resolved": "packages/apidom-parser-adapter-asyncapi-json-2",
"link": true
},
+ "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-3": {
+ "resolved": "packages/apidom-parser-adapter-asyncapi-json-3",
+ "link": true
+ },
"node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": {
"resolved": "packages/apidom-parser-adapter-asyncapi-yaml-2",
"link": true
@@ -25988,6 +25992,7 @@
"@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-rc.3",
+ "@swagger-api/apidom-parser-adapter-asyncapi-json-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-json": "^1.0.0-rc.3",
@@ -26076,7 +26081,7 @@
},
"packages/apidom-ns-asyncapi-3": {
"name": "@swagger-api/apidom-ns-asyncapi-3",
- "version": "1.0.0-beta.0",
+ "version": "1.0.0-rc.3",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.26.10",
@@ -26292,6 +26297,20 @@
"ramda-adjunct": "^5.0.0"
}
},
+ "packages/apidom-parser-adapter-asyncapi-json-3": {
+ "name": "@swagger-api/apidom-parser-adapter-asyncapi-json-3",
+ "version": "1.0.0-rc.3",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime-corejs3": "^7.26.10",
+ "@swagger-api/apidom-core": "^1.0.0-rc.3",
+ "@swagger-api/apidom-ns-asyncapi-3": "^1.0.0-rc.3",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-rc.3",
+ "@types/ramda": "~0.30.0",
+ "ramda": "~0.30.0",
+ "ramda-adjunct": "^5.0.0"
+ }
+ },
"packages/apidom-parser-adapter-asyncapi-yaml-2": {
"name": "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2",
"version": "1.0.0-rc.3",
@@ -26313,7 +26332,7 @@
"dependencies": {
"@babel/runtime-corejs3": "^7.26.10",
"@swagger-api/apidom-core": "^1.0.0-rc.3",
- "@swagger-api/apidom-ns-asyncapi-3": "1.0.0-beta.0",
+ "@swagger-api/apidom-ns-asyncapi-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-rc.3",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",
diff --git a/packages/apidom-ls/package.json b/packages/apidom-ls/package.json
index 933003d08d..6574fa24b4 100644
--- a/packages/apidom-ls/package.json
+++ b/packages/apidom-ls/package.json
@@ -106,6 +106,7 @@
"@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-rc.3",
+ "@swagger-api/apidom-parser-adapter-asyncapi-json-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-json": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-rc.3",
diff --git a/packages/apidom-ls/src/utils/utils.ts b/packages/apidom-ls/src/utils/utils.ts
index ecdce4c9c2..da916e4599 100644
--- a/packages/apidom-ls/src/utils/utils.ts
+++ b/packages/apidom-ls/src/utils/utils.ts
@@ -6,6 +6,7 @@ import * as openapi31xAdapterJson from '@swagger-api/apidom-parser-adapter-opena
import * as openapi31xAdapterYaml from '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1';
import * as asyncapi2AdapterJson from '@swagger-api/apidom-parser-adapter-asyncapi-json-2';
import * as asyncapi2AdapterYaml from '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2';
+import * as asyncapi3AdapterJson from '@swagger-api/apidom-parser-adapter-asyncapi-json-3';
import * as asyncapi3AdapterYaml from '@swagger-api/apidom-parser-adapter-asyncapi-yaml-3';
import * as adsAdapterJson from '@swagger-api/apidom-parser-adapter-api-design-systems-json';
import * as adsAdapterYaml from '@swagger-api/apidom-parser-adapter-api-design-systems-yaml';
@@ -836,7 +837,6 @@ export async function findNamespace(
mediaType: asyncapi2AdapterYaml.mediaTypes.findBy(version, 'yaml'),
};
}
-
if (await asyncapi3AdapterYaml.detect(text)) {
const asyncapi3YamlMatch = text.match(asyncapi3AdapterYaml.detectionRegExp)!;
const groups = asyncapi3YamlMatch.groups!;
@@ -850,6 +850,19 @@ export async function findNamespace(
};
}
+ if (await asyncapi3AdapterJson.detect(text)) {
+ const asyncapi3JsonMatch = text.match(asyncapi3AdapterJson.detectionRegExp)!;
+ const groups = asyncapi3JsonMatch.groups!;
+ const version = groups.version_json;
+
+ return {
+ namespace: 'asyncapi',
+ version,
+ format: 'JSON',
+ mediaType: asyncapi3AdapterJson.mediaTypes.findBy(version, 'json'),
+ };
+ }
+
if (await openapi2AdapterJson.detect(text)) {
const openapi2JsonMatch = text.match(openapi2AdapterJson.detectionRegExp)!;
const groups = openapi2JsonMatch.groups!;
diff --git a/packages/apidom-ns-asyncapi-3/package.json b/packages/apidom-ns-asyncapi-3/package.json
index 25a0abbbb6..8e5d9be2f3 100644
--- a/packages/apidom-ns-asyncapi-3/package.json
+++ b/packages/apidom-ns-asyncapi-3/package.json
@@ -1,6 +1,6 @@
{
"name": "@swagger-api/apidom-ns-asyncapi-3",
- "version": "1.0.0-beta.0",
+ "version": "1.0.0-rc.3",
"description": "AsyncAPI 3.x.y namespace for ApiDOM.",
"publishConfig": {
"access": "public",
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/.eslintignore b/packages/apidom-parser-adapter-asyncapi-json-3/.eslintignore
new file mode 100644
index 0000000000..23853b909a
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/.eslintignore
@@ -0,0 +1,8 @@
+/**/*.js
+/**/*.mjs
+/**/*.cjs
+/dist
+/types
+/config
+/.nyc_output
+/node_modules
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/.gitignore b/packages/apidom-parser-adapter-asyncapi-json-3/.gitignore
new file mode 100644
index 0000000000..9b4d60ee63
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/.gitignore
@@ -0,0 +1,7 @@
+/src/**/*.mjs
+/src/**/*.cjs
+/test/**/*.mjs
+/dist
+/types
+/NOTICE
+/swagger-api-apidom-parser-adapter-asyncapi-json-3-*.tgz
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/.mocharc.json b/packages/apidom-parser-adapter-asyncapi-json-3/.mocharc.json
new file mode 100644
index 0000000000..7e6d84b72e
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/.mocharc.json
@@ -0,0 +1,8 @@
+{
+ "extensions": ["ts"],
+ "loader": "ts-node/esm",
+ "recursive": true,
+ "spec": "test/**/*.mjs",
+ "file": ["test/mocha-bootstrap.ts"],
+ "ignore": ["test/perf/**/*.ts"]
+}
\ No newline at end of file
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/.npmrc b/packages/apidom-parser-adapter-asyncapi-json-3/.npmrc
new file mode 100644
index 0000000000..4b82d2e7bb
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/.npmrc
@@ -0,0 +1,2 @@
+save-prefix="="
+save=false
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/CHANGELOG.md b/packages/apidom-parser-adapter-asyncapi-json-3/CHANGELOG.md
new file mode 100644
index 0000000000..e9fb6ecf59
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/CHANGELOG.md
@@ -0,0 +1,4 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
\ No newline at end of file
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/README.md b/packages/apidom-parser-adapter-asyncapi-json-3/README.md
new file mode 100644
index 0000000000..e01533bdf1
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/README.md
@@ -0,0 +1,93 @@
+# @swagger-api/apidom-parser-adapter-asyncapi-json-3
+
+`@swagger-api/apidom-parser-adapter-asyncapi-json-3` is a parser adapter for following AsyncAPI specification versions defined in [JSON format](https://www.json.org/json-en.html):
+
+- [AsyncAPI 3.0.0 specification](https://github.com/asyncapi/spec/blob/v3.0.0/spec/asyncapi.md)
+- [AsyncAPI 3.0.1 specification](https://github.com/asyncapi/spec/blob/v3.0.1/spec/asyncapi.md)
+
+Under the hood this adapter uses [@swagger-api/apidom-parser-adapter-json](https://github.com/swagger-api/apidom/tree/main/packages/apidom-parser-adapter-json)
+to parse a source string into generic ApiDOM in [base ApiDOM namespace](https://github.com/swagger-api/apidom/tree/main/packages/apidom-core#base-namespace)
+which is then refracted with [AsyncApi 3.x.y Refractors](https://github.com/swagger-api/apidom/tree/main/packages/apidom-ns-asyncapi-3#refractors).
+
+## Installation
+
+After [prerequisites](https://github.com/swagger-api/apidom/blob/main/README.md#prerequisites) for installing this package are satisfied, you can install it
+via [npm CLI](https://docs.npmjs.com/cli) by running the following command:
+
+```sh
+ $ npm install @swagger-api/apidom-parser-adapter-asyncapi-json-3
+```
+
+## Parser adapter API
+
+This parser adapter is fully compatible with parser adapter interface required by [@swagger-api/apidom-parser](https://github.com/swagger-api/apidom/tree/main/packages/apidom-parser#mounting-parser-adapters)
+and implements all required properties.
+
+### mediaTypes
+
+Defines list of media types that this parser adapter recognizes.
+
+```js
+[
+ 'application/vnd.aai.asyncapi;version=3.0.0',
+ 'application/vnd.aai.asyncapi+json;version=3.0.0',
+ 'application/vnd.aai.asyncapi;version=3.0.1',
+ 'application/vnd.aai.asyncapi+json;version=3.0.1',
+]
+```
+
+### detect
+
+[Detection](https://github.com/swagger-api/apidom/blob/main/packages/apidom-parser-adapter-asyncapi-json-3/src/adapter.ts#L18) is based on a regular expression matching required AsyncApi 3.0.0 specification symbols in JSON format.
+
+### namespace
+
+This adapter exposes an instance of [AsyncApi 3.x.y ApiDOM namespace](https://github.com/swagger-api/apidom/tree/main/packages/apidom-ns-asyncapi-3#asyncapi-3xy-namespace).
+
+### parse
+
+`parse` function consumes various options as a second argument. Here is a list of these options:
+
+Option | Type | Default | Description
+--- | --- | --- | ---
+`specObj` | `Object` | [Specification Object](https://github.com/swagger-api/apidom/blob/main/packages/apidom-ns-asyncapi-3/src/refractor/specification.ts) | This specification object drives the JSON AST transformation to AsyncAPI 3.x ApiDOM namespace.
+`sourceMap` | `Boolean` | `false` | Indicate whether to generate source maps.
+`refractorOpts` | `Object` | `{}` | Refractor options are [passed to refractors](https://github.com/swagger-api/apidom/tree/main/packages/apidom-ns-asyncapi-3#refractor-plugins) during refracting phase.
+
+All unrecognized arbitrary options will be ignored.
+
+## Usage
+
+This parser adapter can be used directly or indirectly via [@swagger-api/apidom-parser](https://github.com/swagger-api/apidom/tree/main/packages/apidom-parser).
+
+### Direct usage
+
+During direct usage you don't need to provide `mediaType` as the `parse` function is already pre-bound
+with [supported media types](#mediatypes).
+
+```js
+import { parse, detect } from '@swagger-api/apidom-parser-adapter-asyncapi-json-3';
+
+// detecting
+await detect('{"asyncapi": "3.0.0"}'); // => true
+await detect('{"asyncapi": "3.0.1"}'); // => true
+await detect('test'); // => false
+
+// parsing
+const parseResult = await parse('{"asyncapi": "3.0.0"}', { sourceMap: true });
+```
+
+### Indirect usage
+
+You can omit the `mediaType` option here, but please read [Word on detect vs mediaTypes](https://github.com/swagger-api/apidom/tree/main/packages/apidom-parser#word-on-detect-vs-mediatypes) before you do so.
+
+```js
+import ApiDOMParser from '@swagger-api/apidom-parser';
+import * as asyncApiJsonAdapter from '@swagger-api/apidom-parser-adapter-asyncapi-json-3';
+
+const parser = new ApiDOMParser();
+
+parser.use(asyncApiJsonAdapter);
+
+const parseResult = await parser.parse('{"asyncapi": "3.0.1"}', { mediaType: asyncApiJsonAdapter.mediaTypes.latest('json') });
+```
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/config/api-extractor/api-extractor.json b/packages/apidom-parser-adapter-asyncapi-json-3/config/api-extractor/api-extractor.json
new file mode 100644
index 0000000000..40bee5b261
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/config/api-extractor/api-extractor.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
+ "extends": "../../../../api-extractor.json",
+ "mainEntryPointFilePath": "../../types/adapter.d.ts"
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/browser.config.js b/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/browser.config.js
new file mode 100644
index 0000000000..3e21580d6e
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/browser.config.js
@@ -0,0 +1,92 @@
+import path from 'node:path';
+import { nonMinimizeTrait, minimizeTrait } from './traits.config.js';
+
+const browser = {
+ mode: 'production',
+ entry: ['./src/adapter.ts'],
+ target: 'web',
+ performance: {
+ maxEntrypointSize: 2300000,
+ maxAssetSize: 2300000,
+ },
+ output: {
+ path: path.resolve('./dist'),
+ filename: 'apidom-parser-adapter-asyncapi-json-3.browser.js',
+ libraryTarget: 'umd',
+ library: 'apidomParserAdapterAsyncApiJson3',
+ },
+ resolve: {
+ extensions: ['.ts', '.mjs', '.js', '.json'],
+ fallback: {
+ fs: false,
+ path: false,
+ },
+ },
+ module: {
+ rules: [
+ {
+ test: /\.wasm$/,
+ loader: 'file-loader',
+ type: 'javascript/auto',
+ },
+ {
+ test: /\.(ts|js)?$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ babelrc: true,
+ rootMode: 'upward',
+ },
+ },
+ },
+ ],
+ },
+ ...nonMinimizeTrait,
+};
+
+const browserMin = {
+ mode: 'production',
+ entry: ['./src/adapter.ts'],
+ target: 'web',
+ performance: {
+ maxEntrypointSize: 350000,
+ maxAssetSize: 350000,
+ },
+ output: {
+ path: path.resolve('./dist'),
+ filename: 'apidom-parser-adapter-asyncapi-json-3.browser.min.js',
+ libraryTarget: 'umd',
+ library: 'apidomParserAdapterAsyncApiJson3',
+ },
+ resolve: {
+ extensions: ['.ts', '.mjs', '.js', '.json'],
+ fallback: {
+ fs: false,
+ path: false,
+ },
+ },
+ module: {
+ rules: [
+ {
+ test: /\.wasm$/,
+ loader: 'file-loader',
+ type: 'javascript/auto',
+ },
+ {
+ test: /\.(ts|js)?$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ babelrc: true,
+ rootMode: 'upward',
+ },
+ },
+ },
+ ],
+ },
+ ...minimizeTrait,
+};
+
+export default [browser, browserMin];
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/traits.config.js b/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/traits.config.js
new file mode 100644
index 0000000000..9043521175
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/config/webpack/traits.config.js
@@ -0,0 +1,32 @@
+import webpack from 'webpack';
+import TerserPlugin from 'terser-webpack-plugin';
+
+export const nonMinimizeTrait = {
+ optimization: {
+ minimize: false,
+ usedExports: false,
+ concatenateModules: false,
+ },
+};
+
+export const minimizeTrait = {
+ plugins: [
+ new webpack.LoaderOptionsPlugin({
+ minimize: true,
+ }),
+ ],
+ optimization: {
+ minimizer: [
+ new TerserPlugin({
+ terserOptions: {
+ compress: {
+ warnings: false,
+ },
+ output: {
+ comments: false,
+ },
+ },
+ }),
+ ],
+ },
+};
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/package.json b/packages/apidom-parser-adapter-asyncapi-json-3/package.json
new file mode 100644
index 0000000000..4735555777
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/package.json
@@ -0,0 +1,63 @@
+{
+ "name": "@swagger-api/apidom-parser-adapter-asyncapi-json-3",
+ "version": "1.0.0-rc.3",
+ "description": "Parser adapter for parsing JSON documents into AsyncAPI 3.x.y namespace.",
+ "publishConfig": {
+ "access": "public",
+ "registry": "https://registry.npmjs.org"
+ },
+ "type": "module",
+ "sideEffects": false,
+ "unpkg": "./dist/apidom-parser-apdater-asyncapi-json-3.browser.min.js",
+ "main": "./src/adapter.cjs",
+ "exports": {
+ "types": "./types/apidom-parser-adapter-asyncapi-json-3.d.ts",
+ "import": "./src/adapter.mjs",
+ "require": "./src/adapter.cjs"
+ },
+ "types": "./types/apidom-parser-adapter-asyncapi-json-3.d.ts",
+ "scripts": {
+ "build": "npm run clean && run-p --max-parallel ${CPU_CORES:-2} typescript:declaration build:es build:cjs build:umd:browser",
+ "build:es": "cross-env BABEL_ENV=es babel src --out-dir src --extensions '.ts' --out-file-extension '.mjs' --root-mode 'upward'",
+ "build:cjs": "cross-env BABEL_ENV=cjs babel src --out-dir src --extensions '.ts' --out-file-extension '.cjs' --root-mode 'upward'",
+ "build:umd:browser": "cross-env BABEL_ENV=browser webpack --config config/webpack/browser.config.js --progress",
+ "lint": "eslint ./",
+ "lint:fix": "eslint ./ --fix",
+ "clean": "rimraf --glob 'src/**/*.mjs' 'src/**/*.cjs' ./dist ./types",
+ "typescript:check-types": "tsc --noEmit && tsc -p ./test/tsconfig.json --noEmit",
+ "typescript:declaration": "tsc -p tsconfig.declaration.json && api-extractor run -l -c ./config/api-extractor/api-extractor.json",
+ "test": "NODE_ENV=test ts-mocha --exit",
+ "perf": "cross-env BABEL_ENV=es babel ./test/perf/index.ts --out-file ./test/perf/index.mjs --root-mode 'upward' && cross-env NODE_ENV=test node ./test/perf/index.mjs",
+ "perf:lexical-analysis": "cross-env BABEL_ENV=es babel ./test/perf/lexical-analysis.ts --out-file ./test/perf/lexical-analysis.mjs --root-mode 'upward' && cross-env NODE_ENV=test node ./test/perf/lexical-analysis.mjs",
+ "perf:syntactic-analysis": "cross-env BABEL_ENV=es babel ./test/perf/syntactic-analysis.ts --out-file ./test/perf/syntactic-analysis.mjs --root-mode 'upward' && cross-env NODE_ENV=test node ./test/perf/syntactic-analysis.mjs",
+ "perf:refract": "cross-env BABEL_ENV=es babel ./test/perf/refract.ts --out-file ./test/perf/refract.mjs --root-mode 'upward' && cross-env NODE_ENV=test node ./test/perf/refract.mjs",
+ "perf:parse": "cross-env BABEL_ENV=es babel ./test/perf/parse.ts --out-file ./test/perf/parse.mjs --root-mode 'upward' && cross-env NODE_ENV=test node ./test/perf/parse.mjs",
+ "prepack": "copyfiles -u 3 ../../LICENSES/* LICENSES && copyfiles -u 2 ../../NOTICE .",
+ "postpack": "rimraf NOTICE LICENSES"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/swagger-api/apidom.git"
+ },
+ "author": "Shikha Lakhotia",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime-corejs3": "^7.26.10",
+ "@swagger-api/apidom-core": "^1.0.0-rc.3",
+ "@swagger-api/apidom-ns-asyncapi-3": "^1.0.0-rc.3",
+ "@swagger-api/apidom-parser-adapter-json": "^1.0.0-rc.3",
+ "@types/ramda": "~0.30.0",
+ "ramda": "~0.30.0",
+ "ramda-adjunct": "^5.0.0"
+ },
+ "files": [
+ "src/**/*.mjs",
+ "src/**/*.cjs",
+ "dist/",
+ "types/apidom-parser-adapter-asyncapi-json-3.d.ts",
+ "LICENSES",
+ "NOTICE",
+ "README.md",
+ "CHANGELOG.md"
+ ]
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/src/adapter.ts b/packages/apidom-parser-adapter-asyncapi-json-3/src/adapter.ts
new file mode 100644
index 0000000000..dd2d3611d9
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/src/adapter.ts
@@ -0,0 +1,45 @@
+import { propOr, omit } from 'ramda';
+import { isNotUndefined } from 'ramda-adjunct';
+import { ParseResultElement, createNamespace } from '@swagger-api/apidom-core';
+import { parse as parseJSON, detect as detectJSON } from '@swagger-api/apidom-parser-adapter-json';
+import asyncApiNamespace, { AsyncApi3Element } from '@swagger-api/apidom-ns-asyncapi-3';
+
+export { default as mediaTypes } from './media-types.ts';
+
+/**
+ * @public
+ */
+export const detectionRegExp =
+ /"asyncapi"\s*:\s*"(?3\.(?:[1-9]\d*|0)\.(?:[1-9]\d*|0))"/;
+
+/**
+ * @public
+ */
+export const detect = async (source: string): Promise =>
+ detectionRegExp.test(source) && (await detectJSON(source));
+
+/**
+ * @public
+ */
+export const parse = async (
+ source: string,
+ options: Record = {},
+): Promise => {
+ const refractorOpts: Record = propOr({}, 'refractorOpts', options);
+ const parserOpts = omit(['refractorOpts'], options);
+ const parseResultElement = await parseJSON(source, parserOpts);
+ const { result } = parseResultElement;
+
+ if (isNotUndefined(result)) {
+ const asyncApiElement = AsyncApi3Element.refract(result, refractorOpts);
+ asyncApiElement.classes.push('result');
+ parseResultElement.replaceResult(asyncApiElement);
+ }
+
+ return parseResultElement;
+};
+
+/**
+ * @public
+ */
+export const namespace = createNamespace(asyncApiNamespace);
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/src/media-types.ts b/packages/apidom-parser-adapter-asyncapi-json-3/src/media-types.ts
new file mode 100644
index 0000000000..a9e624cf78
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/src/media-types.ts
@@ -0,0 +1,11 @@
+import { mediaTypes, AsyncAPIMediaTypes } from '@swagger-api/apidom-ns-asyncapi-3';
+
+/**
+ * @public
+ */
+const jsonMediaTypes = new AsyncAPIMediaTypes(
+ ...mediaTypes.filterByFormat('generic'),
+ ...mediaTypes.filterByFormat('json'),
+);
+
+export default jsonMediaTypes;
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/.eslintrc b/packages/apidom-parser-adapter-asyncapi-json-3/test/.eslintrc
new file mode 100644
index 0000000000..c47eea4f48
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/.eslintrc
@@ -0,0 +1,55 @@
+{
+ "env": {
+ "mocha": true
+ },
+ "globals": {
+ "document": true
+ },
+ "plugins": [
+ "mocha"
+ ],
+ "rules": {
+ "no-void": 0,
+ "func-names": 0,
+ "prefer-arrow-callback": 0,
+ "no-array-constructor": 0,
+ "prefer-rest-params": 0,
+ "no-new-wrappers": 0,
+ "mocha/no-skipped-tests": 2,
+ "mocha/handle-done-callback": 2,
+ "mocha/valid-suite-description": 2,
+ "mocha/no-mocha-arrows": 2,
+ "mocha/no-hooks-for-single-case": 2,
+ "mocha/no-sibling-hooks": 2,
+ "mocha/no-top-level-hooks": 2,
+ "mocha/no-identical-title": 2,
+ "mocha/no-nested-tests": 2,
+ "mocha/no-exclusive-tests": 2,
+ "no-underscore-dangle": 0,
+ "import/no-relative-packages": 0,
+ "@typescript-eslint/naming-convention": [
+ "error",
+ {
+ "selector": "variable",
+ "format": ["camelCase", "PascalCase", "UPPER_CASE"],
+ "leadingUnderscore": "forbid"
+ },
+ {
+ "selector": "variable",
+ "format": null,
+ "filter": {
+ "regex": "^__dirname$",
+ "match": true
+ }
+ },
+ {
+ "selector": "variable",
+ "format": null,
+ "filter": {
+ "regex": "^__filename$",
+ "match": true
+ }
+ }
+ ]
+ }
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/__snapshots__/adapter.mjs.snap b/packages/apidom-parser-adapter-asyncapi-json-3/test/__snapshots__/adapter.mjs.snap
new file mode 100644
index 0000000000..924fb82588
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/__snapshots__/adapter.mjs.snap
@@ -0,0 +1,985 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`adapter should parse 1`] = `
+(ParseResultElement
+ (AsyncApi3Element
+ (MemberElement
+ (StringElement)
+ (AsyncApiVersionElement))
+ (MemberElement
+ (StringElement)
+ (IdentifierElement))
+ (MemberElement
+ (StringElement)
+ (InfoElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ContactElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (LicenseElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ServersElement
+ (MemberElement
+ (StringElement)
+ (ServerElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ServerVariableElement
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement)
+ (StringElement)))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (SecuritySchemeElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement))))))))
+ (MemberElement
+ (StringElement)
+ (ServerBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaServerBindingElement))))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))))
+ (MemberElement
+ (StringElement)
+ (ServerElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ServerBindingsElement
+ (MemberElement
+ (StringElement)
+ (JmsServerBindingElement))))))))
+ (MemberElement
+ (StringElement)
+ (DefaultContentTypeElement))
+ (MemberElement
+ (StringElement)
+ (ChannelsElement
+ (MemberElement
+ (StringElement)
+ (ChannelElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (MessagesElement
+ (MemberElement
+ (StringElement)
+ (MessageElement
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))))
+ (MemberElement
+ (StringElement)
+ (CorrelationIDElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (MessageBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaMessageBindingElement
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (MessageExampleElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (MessageTraitElement
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (CorrelationIDElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (MessageBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaMessageBindingElement
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (MessageExampleElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))))))))))
+ (MemberElement
+ (StringElement)
+ (ParametersElement
+ (MemberElement
+ (StringElement)
+ (ParameterElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement)))
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement)))))
+ (MemberElement
+ (StringElement)
+ (ChannelBindingsElement
+ (MemberElement
+ (StringElement)
+ (AmqpChannelBindingElement))))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ComponentsElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (SchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (MultiFormatSchemaElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (SchemaElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (MessageElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (SecuritySchemeElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ParameterElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (CorrelationIDElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (OperationTraitElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (MessageTraitElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ServerBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaServerBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ChannelBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaChannelBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (OperationBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaOperationBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (MessageBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaMessageBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ServerElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ServerVariableElement
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement)))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ChannelElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (OperationElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (OperationReplyElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (OperationReplyAddressElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (TagElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))))))
+ (MemberElement
+ (StringElement)
+ (OperationsElement
+ (MemberElement
+ (StringElement)
+ (OperationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (TagsElement
+ (TagElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (OperationBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaOperationBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (OperationTraitElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (OperationBindingsElement
+ (MemberElement
+ (StringElement)
+ (KafkaOperationBindingElement))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (SecuritySchemeElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement))))))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (SecuritySchemeElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))
+ (MemberElement
+ (StringElement)
+ (ObjectElement))))
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (StringElement)
+ (StringElement))))))))
+ (MemberElement
+ (StringElement)
+ (ExternalDocumentationElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement)))))
+ (MemberElement
+ (StringElement)
+ (OperationReplyElement
+ (MemberElement
+ (StringElement)
+ (OperationReplyAddressElement
+ (MemberElement
+ (StringElement)
+ (StringElement))
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement))))
+ (MemberElement
+ (StringElement)
+ (ArrayElement
+ (ReferenceElement
+ (MemberElement
+ (StringElement)
+ (StringElement)))))))))))))
+`;
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/adapter.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/adapter.ts
new file mode 100644
index 0000000000..cf8d73a5c0
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/adapter.ts
@@ -0,0 +1,94 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { assert, expect } from 'chai';
+import { isParseResultElement, sexprs } from '@swagger-api/apidom-core';
+import { isAsyncApi3Element } from '@swagger-api/apidom-ns-asyncapi-3';
+
+import * as adapter from '../src/adapter.ts';
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const jsonSpec = fs.readFileSync(path.join(dirname, 'fixtures', 'sample-api.json')).toString();
+const yamlSpec = fs.readFileSync(path.join(dirname, 'fixtures', 'sample-api.yaml')).toString();
+
+describe('adapter', function () {
+ context('given definition in JSON format', function () {
+ specify('should detect proper media type', async function () {
+ assert.isTrue(await adapter.detect(jsonSpec));
+ });
+
+ specify('should detect minor version bump', async function () {
+ assert.isTrue(await adapter.detect('{"asyncapi": "3.25.0"}'));
+ });
+
+ specify('should detect patch version bump', async function () {
+ assert.isTrue(await adapter.detect('{"asyncapi": "3.6.1"}'));
+ });
+
+ specify('should detect minor and patch version bump', async function () {
+ assert.isTrue(await adapter.detect('{"asyncapi": "3.25.1"}'));
+ });
+ });
+
+ context('given definition in YAML 1.3 format', function () {
+ specify('should detect proper media type', async function () {
+ assert.isFalse(await adapter.detect(yamlSpec));
+ });
+ });
+
+ context('given definition of unknown type', function () {
+ specify('should detect proper media type', async function () {
+ assert.isFalse(await adapter.detect('"openapi": "2.1.0"'));
+ });
+ });
+
+ it('should parse', async function () {
+ const parseResult = await adapter.parse(jsonSpec, { sourceMap: true });
+
+ assert.isTrue(isParseResultElement(parseResult));
+ assert.isTrue(isAsyncApi3Element(parseResult.api));
+ expect(sexprs(parseResult)).toMatchSnapshot();
+ });
+
+ context('given zero byte empty file', function () {
+ specify('should return empty parse result', async function () {
+ const parseResult = await adapter.parse('', { sourceMap: true });
+
+ assert.isTrue(parseResult.isEmpty);
+ });
+ });
+
+ context('given non-zero byte empty file', function () {
+ specify('should return empty parser result', async function () {
+ const parseResult = await adapter.parse(' ', { sourceMap: true });
+
+ assert.isTrue(parseResult.isEmpty);
+ });
+ });
+
+ context('given invalid json file', function () {
+ specify('should return empty parser result', async function () {
+ const parseResult = await adapter.parse(' a ', { sourceMap: true });
+
+ assert.isTrue(parseResult.isEmpty);
+ });
+ });
+
+ context('detectionRegExp', function () {
+ specify('should detect version ranges in forward compatible way', function () {
+ assert.isTrue(adapter.detectionRegExp.test('"asyncapi": "3.0.0"'));
+ assert.isTrue(adapter.detectionRegExp.test('"asyncapi": "3.0.145"'));
+ assert.isTrue(adapter.detectionRegExp.test('"asyncapi": "3.0.1"'));
+ });
+
+ specify('should reject invalid version ranges', function () {
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "2.0.0"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "2.1.0"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "2.1.1"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "2.5.0"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "2.6.01"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "3.6.01"'));
+ assert.isFalse(adapter.detectionRegExp.test('"asyncapi": "3.06.0"'));
+ });
+ });
+});
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.json b/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.json
new file mode 100644
index 0000000000..f1cbd29430
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.json
@@ -0,0 +1,458 @@
+{
+ "asyncapi": "3.0.0",
+ "id": "urn:com:smartylighting:streetlights:server",
+ "info": {
+ "title": "AsyncAPI Sample App",
+ "version": "1.0.1",
+ "description": "This is a sample server.",
+ "termsOfService": "http://asyncapi.org/terms/",
+ "contact": {
+ "name": "API Support",
+ "url": "http://www.asyncapi.org/support",
+ "email": "support@asyncapi.org"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "tags": [
+ {
+ "name": "topLevelTag",
+ "description": "topLevelTag description",
+ "externalDocs": {
+ "description": "description of topLevelTag external docs",
+ "url": "https://example.com/topLevelTag"
+ }
+ }
+ ],
+ "externalDocs": {
+ "description": "description of this document external docs",
+ "url": "https://example.com/document"
+ }
+ },
+ "servers": {
+ "production": {
+ "host": "{username}.gigantic-server.com",
+ "protocol": "kafka",
+ "protocolVersion": "1.0.0",
+ "pathname": "/v2",
+ "description": "Production server description",
+ "title": "Production server",
+ "summary": "Production server summary.",
+ "variables": {
+ "username": {
+ "enum": ["demo", "demo1", "demo2"],
+ "default": "demo",
+ "description": "This value is assigned by the service provider, in this example `gigantic-server.com`",
+ "examples": ["demo", "demo1", "demo2"]
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": {
+ "type": "apiKey",
+ "description": "Petstore Auth description",
+ "name": "Petstore Auth",
+ "in": "password",
+ "scheme": "Authorization",
+ "bearerFormat": "JWT",
+ "flows": {
+ "implicit": {},
+ "password": {},
+ "clientCredentials": {},
+ "authorizationCode": {}
+ },
+ "openIdConnectUrl": "security-scheme-openIdConnectUrl",
+ "scopes": ["write:pets", "read:pets"]
+ }
+ }
+ ],
+ "bindings": {
+ "kafka": {}
+ },
+ "tags": [
+ {
+ "name": "serversLevelTag",
+ "description": "serversLevelTag description",
+ "externalDocs": {
+ "description": "description of serversLevelTag external docs",
+ "url": "https://example.com/serversLevelTag"
+ }
+ }
+ ]
+ },
+ "development": {
+ "host": "gigantic-server.com",
+ "protocol": "kafka",
+ "bindings": {
+ "jms": {}
+ }
+ }
+ },
+ "defaultContentType": "application/json",
+ "channels": {
+ "userSignedUp": {
+ "address": "users.{userId}",
+ "title": "Users channel",
+ "description": "This channel is used to exchange messages about user events.",
+ "summary": "Exchange messages about user events.",
+ "messages": {
+ "userSignedUp": {
+ "headers": {
+ "type": "object"
+ },
+ "payload": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "$ref": "#/components/schemas/user"
+ },
+ "signup": {
+ "$ref": "#/components/schemas/signup"
+ }
+ }
+ },
+ "correlationId": {
+ "description": "correlation id description",
+ "location": "http://asyncapi.com/"
+ },
+ "contentType": "application/json",
+ "name": "name of the message",
+ "title": "title of the message",
+ "summary": "summary of the message",
+ "description": "A longer description of the message",
+ "tags": [
+ {
+ "name": "tag3",
+ "description": "description of tag3",
+ "externalDocs": {
+ "description": "description of tag 3 external docs",
+ "url": "https://example.com/tag3"
+ }
+ }
+ ],
+ "externalDocs": {
+ "description": "description of message 1 external docs",
+ "url": "https://example.com/message-1-external-docs"
+ },
+ "bindings": {
+ "kafka": {
+ "key": {
+ "type": "integer"
+ },
+ "bindingVersion": "0.1.0"
+ }
+ },
+ "examples": [
+ {
+ "headers": { "Content-Type": "application/json" },
+ "payload": "{\"a\":\"b\"}",
+ "name": "example name",
+ "summary": "example summary"
+ }
+ ],
+ "traits": [
+ {
+ "headers": {
+ "type": "object"
+ },
+ "correlationId": {
+ "description": "correlation id description",
+ "location": "http://asyncapi.com/"
+ },
+ "contentType": "application/json",
+ "name": "name of the message trait",
+ "title": "title of the message trait",
+ "summary": "summary of the message trait",
+ "description": "A longer description of the message trait",
+ "tags": [
+ {
+ "name": "tag4",
+ "description": "description of tag4",
+ "externalDocs": {
+ "description": "description of tag 4 external docs",
+ "url": "https://example.com/tag4"
+ }
+ }
+ ],
+ "externalDocs": {
+ "description": "description of message 1 trait external docs",
+ "url": "https://example.com/message-1-trait-external-docs"
+ },
+ "bindings": {
+ "kafka": {
+ "key": {
+ "type": "integer"
+ },
+ "bindingVersion": "0.1.0"
+ }
+ },
+ "examples": [
+ {
+ "headers": { "Content-Type": "application/json" },
+ "payload": "{\"a\":\"b\"}",
+ "name": "example name",
+ "summary": "example summary"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "parameters": {
+ "userId": {
+ "description": "User identifier"
+ }
+ },
+ "servers": [
+ { "$ref": "#/servers/rabbitmqInProd" },
+ { "$ref": "#/servers/rabbitmqInStaging" }
+ ],
+ "bindings": {
+ "amqp": {}
+ },
+ "tags": [
+ {
+ "name": "user",
+ "description": "User-related messages"
+ }
+ ],
+ "externalDocs": {
+ "description": "Find more info here",
+ "url": "https://example.com"
+ }
+ },
+ "user/loggedout": {
+ "$ref": "https://outside.com/#/path/to/channel"
+ }
+ },
+ "components": {
+ "schemas": {
+ "Schema1": {
+ "type": "object"
+ },
+ "Schema2": {
+ "$ref": "#/components/schemas/Schema1"
+ },
+ "Schema3": {
+ "schemaFormat": "application/vnd.aai.asyncapi;version=3.0.0",
+ "schema": {}
+ }
+ },
+ "messages": {
+ "Message1": {},
+ "Message2": {
+ "$ref": "#/components/messages/Message1"
+ }
+ },
+ "securitySchemes": {
+ "SecurityScheme1": {},
+ "SecurityScheme2": {
+ "$ref": "#/components/securitySchemes/SecurityScheme1"
+ }
+ },
+ "parameters": {
+ "Parameter1": {
+ "description": "parameter description",
+ "location": "http://example.com"
+ },
+ "Parameter2": {
+ "$ref": "#/components/parameters/Parameter1"
+ }
+ },
+ "correlationIds": {
+ "CorrelationID1": {},
+ "CorrelationID2": {
+ "$ref": "#/components/correlationIds/CorrelationID1"
+ }
+ },
+ "operationTraits": {
+ "OperationTrait1": {},
+ "OperationTrait2": {
+ "$ref": "#/components/operationTraits/OperationTrait1"
+ }
+ },
+ "messageTraits": {
+ "MessageTrait1": {},
+ "MessageTrait2": {
+ "$ref": "#/components/messageTraits/MessageTrait1"
+ }
+ },
+ "serverBindings": {
+ "ServerBinding1": {
+ "kafka": {}
+ },
+ "ServerBinding2": {
+ "$ref": "#/components/serverBindings/ServerBinding1"
+ }
+ },
+ "channelBindings": {
+ "ChannelBinding1": {
+ "kafka": {}
+ },
+ "ChannelBinding2": {
+ "$ref": "#/components/channelBindings/ChannelBinding1"
+ }
+ },
+ "operationBindings": {
+ "OperationBinding1": {
+ "kafka": {}
+ },
+ "OperationBinding2": {
+ "$ref": "#/components/operationBindings/OperationBinding1"
+ }
+ },
+ "messageBindings": {
+ "MessageBinding1": {
+ "kafka": {}
+ },
+ "MessageBinding2": {
+ "$ref": "#/components/messageBindings/MessageBinding1"
+ }
+ },
+ "servers": {
+ "server1": {},
+ "server2": {
+ "$ref": "#/components/servers/server1"
+ }
+ },
+ "serverVariables": {
+ "port": {
+ "enum": ["8883", "8884"],
+ "default": "8883"
+ },
+ "port1": {
+ "$ref": "#/components/serverVariables/port"
+ }
+ },
+ "channels": {
+ "channel1": {},
+ "channel2": {
+ "$ref": "#/components/channels/channel1"
+ }
+ },
+ "operations": {
+ "SignUp1": {},
+ "SignUp2": {
+ "$ref": "#/components/operations/SignUp1"
+ }
+ },
+ "replies": {
+ "UserReply1": {},
+ "UserReply2": {
+ "$ref": "#/components/replies/UserReply1"
+ }
+ },
+ "replyAddresses": {
+ "UserReplyAddress1": {},
+ "UserReplyAddress2": {
+ "$ref": "#/components/replyAddresses/UserReplyAddress1"
+ }
+ },
+ "externalDocs": {
+ "ExternalDoc1": {},
+ "ExternalDoc2": {
+ "$ref": "#/components/externalDocs/ExternalDoc1"
+ }
+ },
+ "tags": {
+ "UserTag1": {},
+ "UserTag2": {
+ "$ref": "#/components/tags/UserTag1"
+ }
+ }
+ },
+ "operations": {
+ "onUserSignUp": {
+ "title": "User sign up",
+ "summary": "Action to sign a user up.",
+ "description": "A longer description",
+ "channel": {
+ "$ref": "#/channels/userSignup"
+ },
+ "action": "send",
+ "tags": [
+ {
+ "name": "operationTag",
+ "description": "operationTag description",
+ "externalDocs": {
+ "description": "description of operationTag external docs",
+ "url": "https://example.com/operationTag"
+ }
+ }
+ ],
+ "bindings": {
+ "kafka": {}
+ },
+ "traits": [
+ {
+ "title": "Operation trait title",
+ "description": "Operation trait description",
+ "summary": "Operation trait summary",
+ "bindings": {
+ "kafka": {}
+ },
+ "security": [
+ {
+ "petstore_auth": {
+ "type": "apiKey",
+ "description": "Petstore Auth description",
+ "name": "Petstore Auth",
+ "in": "password",
+ "scheme": "Authorization",
+ "bearerFormat": "JWT",
+ "flows": {
+ "implicit": {},
+ "password": {},
+ "clientCredentials": {},
+ "authorizationCode": {}
+ },
+ "openIdConnectUrl": "security-scheme-openIdConnectUrl",
+ "scopes": ["write:pets", "read:pets"]
+ }
+ }
+ ],
+ "externalDocs": {
+ "description": "Find more info here",
+ "url": "https://example.com"
+ }
+ }
+ ],
+ "security": [
+ {
+ "petstore_auth": {
+ "type": "apiKey",
+ "description": "Petstore Auth description",
+ "name": "Petstore Auth",
+ "in": "password",
+ "scheme": "Authorization",
+ "bearerFormat": "JWT",
+ "flows": {
+ "implicit": {},
+ "password": {},
+ "clientCredentials": {},
+ "authorizationCode": {}
+ },
+ "openIdConnectUrl": "security-scheme-openIdConnectUrl",
+ "scopes": ["write:pets", "read:pets"]
+ }
+ }
+ ],
+ "externalDocs": {
+ "description": "Find more info here",
+ "url": "https://example.com"
+ },
+ "messages": [{ "$ref": "#/components/messages/Message1" }],
+ "reply": {
+ "address": {
+ "description": "Reply address description",
+ "location": "http://example.com/reply"
+ },
+ "channel": {
+ "$ref": "#/components/channels/channel1"
+ },
+ "messages": [{ "$ref": "#/components/messages/Message1" }]
+ }
+ }
+ }
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.yaml b/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.yaml
new file mode 100644
index 0000000000..d13011cce9
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/fixtures/sample-api.yaml
@@ -0,0 +1,337 @@
+---
+asyncapi: "3.0.0"
+id: "urn:com:smartylighting:streetlights:server"
+info:
+ title: "AsyncAPI Sample App"
+ version: "1.0.1"
+ description: "This is a sample server."
+ termsOfService: "http://asyncapi.org/terms/"
+ contact:
+ name: "API Support"
+ url: "http://www.asyncapi.org/support"
+ email: "support@asyncapi.org"
+ license:
+ name: "Apache 2.0"
+ url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+ tags:
+ - name: "topLevelTag"
+ description: "topLevelTag description"
+ externalDocs:
+ description: "description of topLevelTag external docs"
+ url: "https://example.com/topLevelTag"
+ externalDocs:
+ description: "description of this document external docs"
+ url: "https://example.com/document"
+servers:
+ production:
+ host: "{username}.gigantic-server.com"
+ protocol: "kafka"
+ protocolVersion: "1.0.0"
+ pathname: "/v2"
+ description: "Production server description"
+ title: "Production server"
+ summary: "Production server summary."
+ variables:
+ username:
+ enum:
+ - "demo"
+ - "demo1"
+ - "demo2"
+ default: "demo"
+ description: "This value is assigned by the service provider, in this example `gigantic-server.com`"
+ examples:
+ - "demo"
+ - "demo1"
+ - "demo2"
+ security:
+ -
+ petstore_auth:
+ type: "apiKey"
+ description: "Petstore Auth description"
+ name: "Petstore Auth"
+ in: "password"
+ scheme: "Authorization"
+ bearerFormat: "JWT"
+ flows:
+ implicit:
+ password:
+ clientCredentials:
+ authorizationCode:
+ openIdConnectUrl: "security-scheme-openIdConnectUrl"
+ scopes:
+ - "write:pets"
+ - "read:pets"
+ bindings:
+ kafka:
+ tags:
+ - name: "serversLevelTag"
+ description: "serversLevelTag description"
+ externalDocs:
+ description: "description of serversLevelTag external docs"
+ url: "https://example.com/serversLevelTag"
+ development:
+ host: "gigantic-server.com"
+ protocol: "kafka"
+ bindings:
+ jms:
+defaultContentType: "application/json"
+channels:
+ userSignedUp:
+ address: "users.{userId}"
+ title: "Users channel"
+ description: "This channel is used to exchange messages about user events."
+ summary: "Exchange messages about user events."
+ messages:
+ userSignedUp:
+ headers:
+ type: "object"
+ payload:
+ type: "object"
+ properties:
+ user:
+ $ref: "#/components/schemas/user"
+ signup:
+ $ref: "#/components/schemas/signup"
+ correlationId:
+ description: "correlation id description"
+ location: "http://asyncapi.com/"
+ contentType: "application/json"
+ name: "name of the message"
+ title: "title of the message"
+ summary: "summary of the message"
+ description: "A longer description of the message"
+ tags:
+ - name: "tag3"
+ description: "description of tag3"
+ externalDocs:
+ description: "description of tag 3 external docs"
+ url: "https://example.com/tag3"
+ externalDocs:
+ description: "description of message 1 external docs"
+ url: "https://example.com/message-1-external-docs"
+ bindings:
+ kafka:
+ key:
+ type: "integer"
+ bindingVersion: "0.1.0"
+ examples:
+ -
+ headers:
+ Content-Type: "application/json"
+ payload: "{"a":"b"}"
+ name: "example name"
+ summary: "example summary"
+ traits:
+ -
+ headers:
+ type: "object"
+ correlationId:
+ description: "correlation id description"
+ location: "http://asyncapi.com/"
+ contentType: "application/json"
+ name: "name of the message trait"
+ title: "title of the message trait"
+ summary: "summary of the message trait"
+ description: "A longer description of the message trait"
+ tags:
+ - name: "tag4"
+ description: "description of tag4"
+ externalDocs:
+ description: "description of tag 4 external docs"
+ url: "https://example.com/tag4"
+ externalDocs:
+ description: "description of message 1 trait external docs"
+ url: "https://example.com/message-1-trait-external-docs"
+ bindings:
+ kafka:
+ key:
+ type: "integer"
+ bindingVersion: "0.1.0"
+ examples:
+ -
+ headers:
+ Content-Type: "application/json"
+ payload: "{"a":"b"}"
+ name: "example name"
+ summary: "example summary"
+ parameters:
+ userId:
+ description: "User identifier"
+ servers:
+ - $ref: "#/servers/rabbitmqInProd"
+ - $ref: "#/servers/rabbitmqInStaging"
+ bindings:
+ amqp:
+ tags:
+ - name: "user"
+ description: "User-related messages"
+ externalDocs:
+ description: "Find more info here"
+ url: "https://example.com"
+ user/loggedout:
+ $ref: "https://outside.com/#/path/to/channel"
+components:
+ schemas:
+ Schema1:
+ type: "object"
+ Schema2:
+ $ref: "#/components/schemas/Schema1"
+ Schema3:
+ schemaFormat: "application/vnd.aai.asyncapi;version=3.0.0"
+ schema:
+ messages:
+ Message1:
+ Message2:
+ $ref: "#/components/messages/Message1"
+ securitySchemes:
+ SecurityScheme1:
+ SecurityScheme2:
+ $ref: "#/components/securitySchemes/SecurityScheme1"
+ parameters:
+ Parameter1:
+ description: "parameter description"
+ location: "http://example.com"
+ Parameter2:
+ $ref: "#/components/parameters/Parameter1"
+ correlationIds:
+ CorrelationID1:
+ CorrelationID2:
+ $ref: "#/components/correlationIds/CorrelationID1"
+ operationTraits:
+ OperationTrait1:
+ OperationTrait2:
+ $ref: "#/components/operationTraits/OperationTrait1"
+ messageTraits:
+ MessageTrait1:
+ MessageTrait2:
+ $ref: "#/components/messageTraits/MessageTrait1"
+ serverBindings:
+ ServerBinding1:
+ kafka:
+ ServerBinding2:
+ $ref: "#/components/serverBindings/ServerBinding1"
+ channelBindings:
+ ChannelBinding1:
+ kafka:
+ ChannelBinding2:
+ $ref: "#/components/channelBindings/ChannelBinding1"
+ operationBindings:
+ OperationBinding1:
+ kafka:
+ OperationBinding2:
+ $ref: "#/components/operationBindings/OperationBinding1"
+ messageBindings:
+ MessageBinding1:
+ kafka:
+ MessageBinding2:
+ $ref: "#/components/messageBindings/MessageBinding1"
+ servers:
+ server1:
+ server2:
+ $ref: "#/components/servers/server1"
+ serverVariables:
+ port:
+ enum:
+ - "8883"
+ - "8884"
+ default: "8883"
+ port1:
+ $ref: "#/components/serverVariables/port"
+ channels:
+ channel1:
+ channel2:
+ $ref: "#/components/channels/channel1"
+ operations:
+ SignUp1:
+ SignUp2:
+ $ref: "#/components/operations/SignUp1"
+ replies:
+ UserReply1:
+ UserReply2:
+ $ref: "#/components/replies/UserReply1"
+ replyAddresses:
+ UserReplyAddress1:
+ UserReplyAddress2:
+ $ref: "#/components/replyAddresses/UserReplyAddress1"
+ externalDocs:
+ ExternalDoc1:
+ ExternalDoc2:
+ $ref: "#/components/externalDocs/ExternalDoc1"
+ tags:
+ UserTag1:
+ UserTag2:
+ $ref: "#/components/tags/UserTag1"
+operations:
+ onUserSignUp:
+ title: "User sign up"
+ summary: "Action to sign a user up."
+ description: "A longer description"
+ channel:
+ $ref: "#/channels/userSignup"
+ action: "send"
+ tags:
+ - name: "operationTag"
+ description: "operationTag description"
+ externalDocs:
+ description: "description of operationTag external docs"
+ url: "https://example.com/operationTag"
+ bindings:
+ kafka:
+ traits:
+ - title: "Operation trait title"
+ description: "Operation trait description"
+ summary: "Operation trait summary"
+ bindings:
+ kafka:
+ security:
+ -
+ petstore_auth:
+ type: "apiKey"
+ description: "Petstore Auth description"
+ name: "Petstore Auth"
+ in: "password"
+ scheme: "Authorization"
+ bearerFormat: "JWT"
+ flows:
+ implicit:
+ password:
+ clientCredentials:
+ authorizationCode:
+ openIdConnectUrl: "security-scheme-openIdConnectUrl"
+ scopes:
+ - "write:pets"
+ - "read:pets"
+ externalDocs:
+ description: "Find more info here"
+ url: "https://example.com"
+ security:
+ -
+ petstore_auth:
+ type: "apiKey"
+ description: "Petstore Auth description"
+ name: "Petstore Auth"
+ in: "password"
+ scheme: "Authorization"
+ bearerFormat: "JWT"
+ flows:
+ implicit:
+ password:
+ clientCredentials:
+ authorizationCode:
+ openIdConnectUrl: "security-scheme-openIdConnectUrl"
+ scopes:
+ - "write:pets"
+ - "read:pets"
+ externalDocs:
+ description: "Find more info here"
+ url: "https://example.com"
+ messages:
+ - $ref: "#/components/messages/Message1"
+ reply:
+ address:
+ description: "Reply address description"
+ location: "http://example.com/reply"
+ channel:
+ $ref: "#/components/channels/channel1"
+ messages:
+ - $ref: "#/components/messages/Message1"
\ No newline at end of file
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/media-types.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/media-types.ts
new file mode 100644
index 0000000000..08be514354
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/media-types.ts
@@ -0,0 +1,16 @@
+import { assert } from 'chai';
+import ApiDOMParser from '@swagger-api/apidom-parser';
+
+import * as asyncApiJsonAdapter from '../src/adapter.ts';
+
+describe('given adapter is used in parser', function () {
+ const parser = new ApiDOMParser().use(asyncApiJsonAdapter);
+
+ context('given AsyncAPI 3.0.0 definition in JSON format', function () {
+ specify('should find appropriate media type', async function () {
+ const mediaType = await parser.findMediaType('{"asyncapi": "3.0.0"}');
+
+ assert.strictEqual(mediaType, 'application/vnd.aai.asyncapi+json;version=3.0.0');
+ });
+ });
+});
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/mocha-bootstrap.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/mocha-bootstrap.ts
new file mode 100644
index 0000000000..aec560d03f
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/mocha-bootstrap.ts
@@ -0,0 +1,11 @@
+import * as chai from 'chai';
+import { jestSnapshotPlugin, addSerializer } from 'mocha-chai-jest-snapshot';
+
+// @ts-ignore
+import * as jestApiDOMSerializer from '../../../scripts/jest-serializer-apidom.mjs';
+// @ts-ignore
+import * as jestStringSerializer from '../../../scripts/jest-serializer-string.mjs';
+
+chai.use(jestSnapshotPlugin());
+addSerializer(jestApiDOMSerializer);
+addSerializer(jestStringSerializer);
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/fixtures/asyncapi.json b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/fixtures/asyncapi.json
new file mode 100644
index 0000000000..edede5c280
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/fixtures/asyncapi.json
@@ -0,0 +1,137 @@
+{
+ "asyncapi": "3.0.0",
+ "id": "urn:com:smartylighting:streetlights:server",
+ "info": {
+ "title": "AsyncAPI Sample App",
+ "version": "1.0.1"
+ },
+ "servers": {
+ "production":{
+ "url": "{username}.gigantic-server.com:{port}/{basePath}",
+ "protocol": "secure-mqtt",
+ "protocolVersion": "1.0.0",
+ "variables": {
+ "username": {
+ "default": "demo",
+ "description": "This value is assigned by the service provider, in this example `gigantic-server.com`",
+ "examples": ["value1", "value2"]
+ },
+ "port": {
+ "enum": [
+ "8883",
+ "8884"
+ ],
+ "default": "8883"
+ },
+ "basePath": {
+ "default": "v2"
+ }
+ },
+ "security": [
+ {
+ "user_pass": []
+ }
+ ]
+ }
+ },
+ "channels": {
+ "user/{userId}/signup": {
+ "description": "This channel is used to exchange messages about users signing up",
+ "parameters": {
+ "userId": {
+ "description": "Id of the user.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "subscribe": {
+ "message": {
+ "description": "A longer description of the message",
+ "payload": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "$ref": "#/components/schemas/user"
+ },
+ "signup": {
+ "$ref": "#/components/schemas/signup"
+ }
+ }
+ }
+ }
+ },
+ "bindings": {
+ "amqp": {
+ "is": "queue",
+ "queue": {
+ "exclusive": true
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "x-extension": "value",
+ "schemas": {
+ "Category": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "Tag": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "messages": {
+ "userSignUp": {
+ "summary": "Action to sign a user up.",
+ "description": "Multiline description of what this action does.\nHere you have another line.\n",
+ "tags": [
+ {
+ "name": "user"
+ },
+ {
+ "name": "signup"
+ }
+ ],
+ "headers": {
+ "type": "object",
+ "properties": {
+ "applicationInstanceId": {
+ "description": "Unique identifier for a given instance of the publishing application",
+ "type": "string"
+ }
+ }
+ },
+ "payload": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "$ref": "#/components/schemas/userCreate"
+ },
+ "signup": {
+ "$ref": "#/components/schemas/signup"
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/index.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/index.ts
new file mode 100644
index 0000000000..94522d856c
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/index.ts
@@ -0,0 +1,24 @@
+import Benchmark from 'benchmark';
+import type { Event } from 'benchmark';
+
+import lexicalAnalysisBench from './lexical-analysis.ts';
+import syntacticAnalysisBench from './syntactic-analysis.ts';
+import refractBench from './refract.ts';
+import parseBench from './parse.ts';
+
+const suite = new Benchmark.Suite();
+
+suite
+ .add(lexicalAnalysisBench)
+ .add(syntacticAnalysisBench)
+ .add(refractBench)
+ .add(parseBench)
+ // add listeners
+ .on('cycle', function (event: Event) {
+ console.info(String(event.target));
+ })
+ .on('complete', function () {
+ console.info('\nAll benchmarks have completed');
+ })
+ // run
+ .run();
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/lexical-analysis.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/lexical-analysis.ts
new file mode 100644
index 0000000000..a66e7db268
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/lexical-analysis.ts
@@ -0,0 +1,37 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import Benchmark from 'benchmark';
+import type { Deferred, Event } from 'benchmark';
+import { lexicalAnalysis } from '@swagger-api/apidom-parser-adapter-json';
+import { fileURLToPath } from 'node:url';
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const fixturePath = path.join(dirname, 'fixtures/asyncapi.json');
+const source = fs.readFileSync(fixturePath).toString();
+
+const options = {
+ name: 'lexical-analysis',
+ defer: true,
+ minSamples: 1400,
+ expected: '1,294 ops/sec ±1.97% (1473 runs sampled)',
+ async fn(deferred: Deferred) {
+ await lexicalAnalysis(source);
+ deferred.resolve();
+ },
+};
+
+export default options;
+
+// we're running as a script
+if (import.meta.url === `file://${process.argv[1]}`) {
+ const bench = new Benchmark({
+ ...options,
+ onComplete(event: Event) {
+ console.info(String(event.target));
+ },
+ onError(event: Event) {
+ console.error(event);
+ },
+ });
+ bench.run();
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/parse.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/parse.ts
new file mode 100644
index 0000000000..af07996e30
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/parse.ts
@@ -0,0 +1,47 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import Benchmark from 'benchmark';
+import type { Deferred, Event } from 'benchmark';
+
+import { parse } from '../../src/adapter.ts';
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const fixturePath = path.join(dirname, 'fixtures/asyncapi.json');
+const source = fs.readFileSync(fixturePath).toString();
+
+const options = {
+ name: 'parse',
+ defer: true,
+ minSamples: 600,
+ expected: '41.22 ops/sec ±1.71% (658 runs sampled)',
+ async fn(deferred: Deferred) {
+ await parse(source);
+ deferred.resolve();
+ },
+};
+
+/**
+ * # Analysis of ApiDOM stages
+ *
+ * Parse stage: 14,56 ms
+ * Lexical Analysis phase: 0,77 ms
+ * Syntactic Analysis phase: 8,13 ms
+ * Refract stage: 9,7 ms
+ */
+
+export default options;
+
+// we're running as a script
+if (import.meta.url === `file://${process.argv[1]}`) {
+ const bench = new Benchmark({
+ ...options,
+ onComplete(event: Event) {
+ console.info(String(event.target));
+ },
+ onError(event: Event) {
+ console.error(event);
+ },
+ });
+ bench.run();
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/refract.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/refract.ts
new file mode 100644
index 0000000000..cb50d4d8da
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/refract.ts
@@ -0,0 +1,38 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import Benchmark from 'benchmark';
+import type { Event } from 'benchmark';
+import { ObjectElement } from '@swagger-api/apidom-core';
+import { AsyncApi3Element } from '@swagger-api/apidom-ns-asyncapi-3';
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const fixturePath = path.join(dirname, 'fixtures/asyncapi.json');
+const source = fs.readFileSync(fixturePath).toString();
+const pojo = JSON.parse(source);
+const genericObjectElement = new ObjectElement(pojo);
+
+const options = {
+ name: 'refract',
+ minSamples: 600,
+ expected: '103 ops/sec ±0.92% (668 runs sampled)',
+ fn() {
+ AsyncApi3Element.refract(genericObjectElement);
+ },
+};
+
+export default options;
+
+// we're running as a script
+if (import.meta.url === `file://${process.argv[1]}`) {
+ const bench = new Benchmark({
+ ...options,
+ onComplete(event: Event) {
+ console.info(String(event.target));
+ },
+ onError(event: Event) {
+ console.error(event);
+ },
+ });
+ bench.run();
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/syntactic-analysis.ts b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/syntactic-analysis.ts
new file mode 100644
index 0000000000..fed54ae7d2
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/perf/syntactic-analysis.ts
@@ -0,0 +1,39 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import Benchmark from 'benchmark';
+import type { Deferred, Event } from 'benchmark';
+import { lexicalAnalysis, syntacticAnalysis } from '@swagger-api/apidom-parser-adapter-json';
+import { fileURLToPath } from 'node:url';
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const fixturePath = path.join(dirname, 'fixtures/asyncapi.json');
+const source = fs.readFileSync(fixturePath).toString();
+const cstP = lexicalAnalysis(source);
+
+const options = {
+ name: 'syntactic-analysis',
+ defer: true,
+ minSamples: 600,
+ expected: '123 ops/sec ±1.38% (676 runs sampled)',
+ async fn(deferred: Deferred) {
+ const cst = await cstP;
+ syntacticAnalysis(cst);
+ deferred.resolve();
+ },
+};
+
+export default options;
+
+// we're running as a script
+if (import.meta.url === `file://${process.argv[1]}`) {
+ const bench = new Benchmark({
+ ...options,
+ onComplete(event: Event) {
+ console.info(String(event.target));
+ },
+ onError(event: Event) {
+ console.error(event);
+ },
+ });
+ bench.run();
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/test/tsconfig.json b/packages/apidom-parser-adapter-asyncapi-json-3/test/tsconfig.json
new file mode 100644
index 0000000000..405aae2d2f
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/test/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "module": "esnext",
+ "moduleResolution": "node"
+ },
+ "include": [
+ "."
+ ]
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.declaration.json b/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.declaration.json
new file mode 100644
index 0000000000..82d128fa80
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.declaration.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationDir": "types",
+ "noEmit": false,
+ "emitDeclarationOnly": true
+ }
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.json b/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.json
new file mode 100644
index 0000000000..5cc50cd885
--- /dev/null
+++ b/packages/apidom-parser-adapter-asyncapi-json-3/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ]
+}
diff --git a/packages/apidom-parser-adapter-asyncapi-yaml-3/package.json b/packages/apidom-parser-adapter-asyncapi-yaml-3/package.json
index 3440c6c0ed..51b02f5d73 100644
--- a/packages/apidom-parser-adapter-asyncapi-yaml-3/package.json
+++ b/packages/apidom-parser-adapter-asyncapi-yaml-3/package.json
@@ -44,7 +44,7 @@
"dependencies": {
"@babel/runtime-corejs3": "^7.26.10",
"@swagger-api/apidom-core": "^1.0.0-rc.3",
- "@swagger-api/apidom-ns-asyncapi-3": "1.0.0-beta.0",
+ "@swagger-api/apidom-ns-asyncapi-3": "^1.0.0-rc.3",
"@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-rc.3",
"@types/ramda": "~0.30.0",
"ramda": "~0.30.0",