Skip to content
Merged
46 changes: 46 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
* [.hasExt(key)](#module_@asyncapi/parser+Channel+hasExt) ⇒ <code>boolean</code>
* [.ext(key)](#module_@asyncapi/parser+Channel+ext) ⇒ <code>any</code>
* [.Components](#module_@asyncapi/parser+Components) ⇐ <code>Base</code>
* [.channels()](#module_@asyncapi/parser+Components+channels) ⇒ <code>Object.&lt;string, Channel&gt;</code>
* [.hasChannels()](#module_@asyncapi/parser+Components+hasChannels) ⇒ <code>boolean</code>
* [.channel(name)](#module_@asyncapi/parser+Components+channel) ⇒ <code>Channel</code>
* [.messages()](#module_@asyncapi/parser+Components+messages) ⇒ <code>Object.&lt;string, Message&gt;</code>
* [.hasMessages()](#module_@asyncapi/parser+Components+hasMessages) ⇒ <code>boolean</code>
* [.message(name)](#module_@asyncapi/parser+Components+message) ⇒ <code>Message</code>
Expand All @@ -91,6 +94,9 @@
* [.securitySchemes()](#module_@asyncapi/parser+Components+securitySchemes) ⇒ <code>Object.&lt;string, SecurityScheme&gt;</code>
* [.hasSecuritySchemes()](#module_@asyncapi/parser+Components+hasSecuritySchemes) ⇒ <code>boolean</code>
* [.securityScheme(name)](#module_@asyncapi/parser+Components+securityScheme) ⇒ <code>SecurityScheme</code>
* [.servers()](#module_@asyncapi/parser+Components+servers) ⇒ <code>Object.&lt;string, Server&gt;</code>
* [.hasServers()](#module_@asyncapi/parser+Components+hasServers) ⇒ <code>boolean</code>
* [.server(name)](#module_@asyncapi/parser+Components+server) ⇒ <code>Server</code>
* [.parameters()](#module_@asyncapi/parser+Components+parameters) ⇒ <code>Object.&lt;string, ChannelParameter&gt;</code>
* [.hasParameters()](#module_@asyncapi/parser+Components+hasParameters) ⇒ <code>boolean</code>
* [.parameter(name)](#module_@asyncapi/parser+Components+parameter) ⇒ <code>ChannelParameter</code>
Expand Down Expand Up @@ -787,6 +793,9 @@ Implements functions to deal with a Components object.
**Mixes**: [<code>MixinSpecificationExtensions</code>](#MixinSpecificationExtensions)

* [.Components](#module_@asyncapi/parser+Components) ⇐ <code>Base</code>
* [.channels()](#module_@asyncapi/parser+Components+channels) ⇒ <code>Object.&lt;string, Channel&gt;</code>
* [.hasChannels()](#module_@asyncapi/parser+Components+hasChannels) ⇒ <code>boolean</code>
* [.channel(name)](#module_@asyncapi/parser+Components+channel) ⇒ <code>Channel</code>
* [.messages()](#module_@asyncapi/parser+Components+messages) ⇒ <code>Object.&lt;string, Message&gt;</code>
* [.hasMessages()](#module_@asyncapi/parser+Components+hasMessages) ⇒ <code>boolean</code>
* [.message(name)](#module_@asyncapi/parser+Components+message) ⇒ <code>Message</code>
Expand All @@ -796,6 +805,9 @@ Implements functions to deal with a Components object.
* [.securitySchemes()](#module_@asyncapi/parser+Components+securitySchemes) ⇒ <code>Object.&lt;string, SecurityScheme&gt;</code>
* [.hasSecuritySchemes()](#module_@asyncapi/parser+Components+hasSecuritySchemes) ⇒ <code>boolean</code>
* [.securityScheme(name)](#module_@asyncapi/parser+Components+securityScheme) ⇒ <code>SecurityScheme</code>
* [.servers()](#module_@asyncapi/parser+Components+servers) ⇒ <code>Object.&lt;string, Server&gt;</code>
* [.hasServers()](#module_@asyncapi/parser+Components+hasServers) ⇒ <code>boolean</code>
* [.server(name)](#module_@asyncapi/parser+Components+server) ⇒ <code>Server</code>
* [.parameters()](#module_@asyncapi/parser+Components+parameters) ⇒ <code>Object.&lt;string, ChannelParameter&gt;</code>
* [.hasParameters()](#module_@asyncapi/parser+Components+hasParameters) ⇒ <code>boolean</code>
* [.parameter(name)](#module_@asyncapi/parser+Components+parameter) ⇒ <code>ChannelParameter</code>
Expand All @@ -817,6 +829,23 @@ Implements functions to deal with a Components object.
* [.hasExt(key)](#module_@asyncapi/parser+Components+hasExt) ⇒ <code>boolean</code>
* [.ext(key)](#module_@asyncapi/parser+Components+ext) ⇒ <code>any</code>

<a name="module_@asyncapi/parser+Components+channels"></a>

#### components.channels() ⇒ <code>Object.&lt;string, Channel&gt;</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)
<a name="module_@asyncapi/parser+Components+hasChannels"></a>

#### components.hasChannels() ⇒ <code>boolean</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)
<a name="module_@asyncapi/parser+Components+channel"></a>

#### components.channel(name) ⇒ <code>Channel</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)

| Param | Type | Description |
| --- | --- | --- |
| name | <code>string</code> | Name of the channel. |

<a name="module_@asyncapi/parser+Components+messages"></a>

#### components.messages() ⇒ <code>Object.&lt;string, Message&gt;</code>
Expand Down Expand Up @@ -868,6 +897,23 @@ Implements functions to deal with a Components object.
| --- | --- | --- |
| name | <code>string</code> | Name of the security schema. |

<a name="module_@asyncapi/parser+Components+servers"></a>

#### components.servers() ⇒ <code>Object.&lt;string, Server&gt;</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)
<a name="module_@asyncapi/parser+Components+hasServers"></a>

#### components.hasServers() ⇒ <code>boolean</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)
<a name="module_@asyncapi/parser+Components+server"></a>

#### components.server(name) ⇒ <code>Server</code>
**Kind**: instance method of [<code>Components</code>](#module_@asyncapi/parser+Components)

| Param | Type | Description |
| --- | --- | --- |
| name | <code>string</code> | Name of the server. |

<a name="module_@asyncapi/parser+Components+parameters"></a>

#### components.parameters() ⇒ <code>Object.&lt;string, ChannelParameter&gt;</code>
Expand Down
2 changes: 1 addition & 1 deletion dist/bundle.js

Large diffs are not rendered by default.

19 changes: 7 additions & 12 deletions lib/asyncapiSchemaFormatParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,13 @@ async function parse({ message, originalAsyncAPIDocument, fileFormat, parsedAsyn
*/
function getMimeTypes() {
return [
'application/vnd.aai.asyncapi;version=2.0.0',
'application/vnd.aai.asyncapi;version=2.1.0',
'application/vnd.aai.asyncapi;version=2.2.0',
'application/vnd.aai.asyncapi+json;version=2.0.0',
'application/vnd.aai.asyncapi+json;version=2.1.0',
'application/vnd.aai.asyncapi+json;version=2.2.0',
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
'application/schema;version=draft-07',
'application/schema+json;version=draft-07',
'application/schema+yaml;version=draft-07',
...['2.0.0', '2.1.0', '2.2.0', '2.3.0'].map((version) => {
return [
`application/vnd.aai.asyncapi;version=${version}`,
`application/vnd.aai.asyncapi+json;version=${version}`,
`application/vnd.aai.asyncapi+yaml;version=${version}`,
];
}).flat().concat(['application/schema;version=draft-07', 'application/schema+json;version=draft-07', 'application/schema+yaml;version=draft-07'])
];
}

Expand Down
46 changes: 46 additions & 0 deletions lib/models/components.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const { createMapOfType, getMapValueOfType, mix } = require('./utils');

const Base = require('./base');
const Channel = require('./channel');
const Message = require('./message');
const Schema = require('./schema');
const SecurityScheme = require('./security-scheme');
const Server = require('./server');
const ChannelParameter = require('./channel-parameter');
const CorrelationId = require('./correlation-id');
const OperationTrait = require('./operation-trait');
Expand All @@ -20,6 +22,28 @@ const MixinSpecificationExtensions = require('../mixins/specification-extensions
* @returns {Components}
*/
class Components extends Base {
/**
* @returns {Object<string, Channel>}
*/
channels() {
return createMapOfType(this._json.channels, Channel);
}

/**
* @returns {boolean}
*/
hasChannels() {
return !!this._json.channels;
}

/**
* @param {string} name - Name of the channel.
* @returns {Channel}
*/
channel(name) {
return getMapValueOfType(this._json.channels, name, Channel);
}

/**
* @returns {Object<string, Message>}
*/
Expand Down Expand Up @@ -85,6 +109,28 @@ class Components extends Base {
securityScheme(name) {
return getMapValueOfType(this._json.securitySchemes, name, SecurityScheme);
}

/**
* @returns {Object<string, Server>}
*/
servers() {
return createMapOfType(this._json.servers, Server);
}

/**
* @returns {boolean}
*/
hasServers() {
return !!this._json.servers;
}

/**
* @param {string} name - Name of the server.
* @returns {Server}
*/
server(name) {
return getMapValueOfType(this._json.servers, name, Server);
}

/**
* @returns {Object<string, ChannelParameter>}
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@asyncapi/parser",
"version": "1.13.2",
"version": "1.14.0-2022-01-release.3",
"description": "JavaScript AsyncAPI parser.",
"main": "lib/index.js",
"types": "types.d.ts",
Expand Down Expand Up @@ -67,7 +67,7 @@
},
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@asyncapi/specs": "^2.11.0",
"@asyncapi/specs": "^2.13.0",
"@fmvilas/pseudo-yaml-ast": "^0.3.1",
"ajv": "^6.10.1",
"js-yaml": "^3.13.1",
Expand All @@ -88,7 +88,7 @@
"branches": [
"master",
{
"name": "2021-09-release",
"name": "2022-01-release",
"prerelease": true
}
],
Expand Down
102 changes: 102 additions & 0 deletions test/models/components_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ const Components = require('../../lib/models/components');
const { assertMixinSpecificationExtensionsInheritance } = require('../mixins/specification-extensions_test');

describe('Components', function() {
describe('#channels()', function() {
it('should return a map of Channel objects', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(typeof d.channels()).to.be.equal('object');
expect(d.channels().test1.constructor.name).to.equal('Channel');
expect(d.channels().test1.json()).to.equal(doc.channels.test1);
expect(d.channels().test2.constructor.name).to.equal('Channel');
expect(d.channels().test2.json()).to.equal(doc.channels.test2);
});

it('should return an empty object if the components field has no defined channels', function() {
const doc = {};
const d = new Components(doc);
expect(typeof d.channels()).to.be.equal('object');
expect(d.channels()).to.deep.equal({});
});
});

describe('#hasChannels()', function() {
it('should return a boolean indicating if the components field has channels', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const docNoChannels = { schemas: {} };
const d = new Components(doc);
const d2 = new Components(docNoChannels);
expect(d.hasChannels()).to.equal(true);
expect(d2.hasChannels()).to.equal(false);
});
});

describe('#channel()', function() {
it('should return a specific Channel object', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel('test1').constructor.name).to.equal('Channel');
expect(d.channel('test1').json()).to.equal(doc.channels.test1);
});

it('should return null if a channel name is not provided', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel()).to.equal(null);
});

it('should return null if a channel name is not found', function() {
const doc = { channels: { test1: { description: 'test1' }, test2: { description: 'test2' } } };
const d = new Components(doc);
expect(d.channel('not found')).to.equal(null);
});
});

describe('#messages()', function() {
it('should return a map of Message objects', function() {
const doc = { messages: { test1: { test: 'test1' }, test2: { test: 'test2' } } };
Expand Down Expand Up @@ -157,6 +208,57 @@ describe('Components', function() {
expect(d.securityScheme('not found')).to.equal(null);
});
});

describe('#servers()', function() {
it('should return a map of Server objects', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(typeof d.servers()).to.be.equal('object');
expect(d.servers().test1.constructor.name).to.equal('Server');
expect(d.servers().test1.json()).to.equal(doc.servers.test1);
expect(d.servers().test2.constructor.name).to.equal('Server');
expect(d.servers().test2.json()).to.equal(doc.servers.test2);
});

it('should return an empty object if the components field has no defined servers', function() {
const doc = {};
const d = new Components(doc);
expect(typeof d.servers()).to.be.equal('object');
expect(d.servers()).to.deep.equal({});
});
});

describe('#hasServers()', function() {
it('should return a boolean indicating if the components field has servers', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const docNoServers = { schemas: {} };
const d = new Components(doc);
const d2 = new Components(docNoServers);
expect(d.hasServers()).to.equal(true);
expect(d2.hasServers()).to.equal(false);
});
});

describe('#server()', function() {
it('should return a specific Server object', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server('test1').constructor.name).to.equal('Server');
expect(d.server('test1').json()).to.equal(doc.servers.test1);
});

it('should return null if a message name is not provided', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server()).to.equal(null);
});

it('should return null if a message name is not found', function() {
const doc = { servers: { test1: { url: 'test1' }, test2: { url: 'test2' } } };
const d = new Components(doc);
expect(d.server('not found')).to.equal(null);
});
});

describe('#parameters()', function() {
it('should return a map of ChannelParameter objects', function() {
Expand Down
Loading