New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@asyncapi/parser

Package Overview
Dependencies
Maintainers
3
Versions
170
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@asyncapi/parser - npm Package Compare versions

Comparing version 0.16.0 to 0.16.1

143

lib/models/asyncapi.js

@@ -21,6 +21,7 @@ const { createMapOfType, getMapKeyOfType, addExtensions } = require('../utils');

assignNameToAnonymousMessages(this);
assignIdToAnonymousSchemas(this);
assignNameToComponentMessages(this);
assignNameToComponentMessages(this);
assignUidToComponentSchemas(this);
assignUidToParameterSchemas(this);
assignIdToAnonymousSchemas(this);
}

@@ -41,3 +42,3 @@

}
/**

@@ -56,3 +57,3 @@ * @returns {string}

}
/**

@@ -79,3 +80,3 @@ * @returns {Object<string, Server>}

}
/**

@@ -87,3 +88,3 @@ * @returns {Object<string, Channel>}

}
/**

@@ -147,3 +148,2 @@ * @returns {string[]}

const messages = new Map();
if (this.hasChannels()) {

@@ -164,9 +164,7 @@ this.channelNames().forEach(channelName => {

}
if (this.hasComponents()) {
Object.values(this.components().messages()).forEach(m => {
messages.set(m.uid(), m);
messages.set(m.uid(), m);
});
}
return messages;

@@ -180,3 +178,2 @@ }

const schemas = new Map();
if (this.hasChannels()) {

@@ -216,9 +213,7 @@ this.channelNames().forEach(channelName => {

}
if (this.hasComponents()) {
Object.values(this.components().schemas()).forEach(s => {
schemas.set(s.uid(), s);
schemas.set(s.uid(), s);
});
}
return schemas;

@@ -228,5 +223,6 @@ }

function assignNameToComponentMessages(doc){
function assignNameToComponentMessages(doc) {
if (doc.hasComponents()) {
for(const [key, m] of Object.entries(doc.components().messages())){
for (const [key, m] of Object.entries(doc.components().messages())) {
if (m.name() === undefined) {

@@ -238,5 +234,25 @@ m.json()['x-parser-message-name'] = key;

}
function assignUidToComponentSchemas(doc){
/**
* Assign parameter keys as uid for the parameter schema.
*
* @param {AsyncAPIDocument} doc
*/
function assignUidToParameterSchemas(doc) {
doc.channelNames().forEach(channelName => {
const channel = doc.channel(channelName);
for (const [parameterKey, parameterSchema] of Object.entries(channel.parameters())) {
parameterSchema.json()['x-parser-schema-id'] = parameterKey;
}
});
}
/**
* Assign uid to component schemas.
*
* @param {AsyncAPIDocument} doc
*/
function assignUidToComponentSchemas(doc) {
if (doc.hasComponents()) {
for(const [key, s] of Object.entries(doc.components().schemas())){
for (const [key, s] of Object.entries(doc.components().schemas())) {
s.json()['x-parser-schema-id'] = key;

@@ -270,5 +286,55 @@ }

function assignIdToAnonymousSchemas(doc) {
let anonymousSchemaCounter = 0;
/**
* Recursively go through each schema and execute callback.
*
* @param {Schema} schema found.
* @param {Function} callback(schema)
* the function that is called foreach schema found.
* schema {Schema}: the found schema.
*/
function recursiveSchema(schema, callback) {
if (schema === null) return;
callback(schema);
if (schema.type() !== null) {
switch (schema.type()) {
case 'object':
const props = schema.properties();
for (const [, propertySchema] of Object.entries(props)) {
recursiveSchema(propertySchema, callback);
}
break;
case 'array':
if (Array.isArray(schema.items())) {
schema.items().forEach(arraySchema => {
recursiveSchema(arraySchema, callback);
});
} else {
recursiveSchema(schema.items(), callback);
}
break;
}
} else {
//check for allOf, oneOf, anyOf
const checkCombiningSchemas = (combineArray) => {
if (combineArray !== null && combineArray.length > 0) {
combineArray.forEach(combineSchema => {
recursiveSchema(combineSchema, callback);;
});
}
}
checkCombiningSchemas(schema.allOf());
checkCombiningSchemas(schema.anyOf());
checkCombiningSchemas(schema.oneOf());
}
}
/**
* Go through each channel and for each parameter, and message payload and headers recursively call the callback for each schema.
*
* @param {AsyncAPIDocument} doc
* @param {Function} callback(schema)
* the function that is called foreach schema found.
* schema {Schema}: the found schema.
*/
function schemaDocument(doc, callback) {
if (doc.hasChannels()) {

@@ -279,5 +345,3 @@ doc.channelNames().forEach(channelName => {

Object.values(channel.parameters()).forEach(p => {
if (p.schema() && !p.schema().$id()) {
p.schema().json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
recursiveSchema(p.schema(), callback);
});

@@ -287,9 +351,4 @@

channel.publish().messages().forEach(m => {
if (m.headers() && !m.headers().$id()) {
m.headers().json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
if (m.payload() && !m.payload().$id()) {
m.payload().json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
recursiveSchema(m.headers(), callback);
recursiveSchema(m.payload(), callback);
});

@@ -299,9 +358,4 @@ }

channel.subscribe().messages().forEach(m => {
if (m.headers() && !m.headers().$id()) {
m.headers().json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
if (m.payload() && !m.payload().$id()) {
m.payload().json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
recursiveSchema(m.headers(), callback);
recursiveSchema(m.payload(), callback);
});

@@ -313,2 +367,17 @@ }

/**
* Gives schemas id to all anonymous schemas.
*
* @param {AsyncAPIDocument} doc
*/
function assignIdToAnonymousSchemas(doc) {
let anonymousSchemaCounter = 0;
const callback = (schema) => {
if (!schema.uid()) {
schema.json()['x-parser-schema-id'] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
};
schemaDocument(doc, callback);
}
module.exports = addExtensions(AsyncAPIDocument);
{
"name": "@asyncapi/parser",
"version": "0.16.0",
"version": "0.16.1",
"description": "JavaScript AsyncAPI parser.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -5,2 +5,10 @@ const { expect } = require('chai');

describe('AsyncAPIDocument', () => {
describe('assignUidToParameterSchemas()', () => {
it('should assign uids to parameters', () => {
const inputDoc = { "channels": { "smartylighting/{streetlightId}": { "parameters": { "streetlightId": { "schema": { "type": "string" } } } } } };
const expectedDoc = { "channels": { "smartylighting/{streetlightId}": { "parameters": { "streetlightId": { "schema": { "type": "string", "x-parser-schema-id": "<anonymous-schema-1>" }, "x-parser-schema-id": "streetlightId" } } } } }
const d = new AsyncAPIDocument(inputDoc);
expect(d.json()).to.be.deep.equal(expectedDoc);
});
});
describe('#ext()', () => {

@@ -7,0 +15,0 @@ it('should support extensions', () => {

@@ -13,6 +13,6 @@ const chai = require('chai');

const inputYAML = fs.readFileSync(path.resolve(__dirname, "./asyncapi.yaml"), 'utf8');
const outputJSON = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"externalDocs":{"x-extension":true,"url":"https://company.com/docs"},"message":{"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"},"x-parser-original-traits":[{"externalDocs":{"url":"https://company.com/docs"}}]}}},"components":{"messages":{"testMessage":{"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}';
const outputJsonNoApplyTraits = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"traits":[{"externalDocs":{"url":"https://company.com/docs"}}],"externalDocs":{"x-extension":true,"url":"https://irrelevant.com"},"message":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}}}},"components":{"messages":{"testMessage":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}},"x-parser-schema-id":"testSchema"}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}';
const outputJSON = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"externalDocs":{"x-extension":true,"url":"https://company.com/docs"},"message":{"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"},"x-parser-original-traits":[{"externalDocs":{"url":"https://company.com/docs"}}]}}},"components":{"messages":{"testMessage":{"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}';
const outputJsonNoApplyTraits = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"traits":[{"externalDocs":{"url":"https://company.com/docs"}}],"externalDocs":{"x-extension":true,"url":"https://irrelevant.com"},"message":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}}}},"components":{"messages":{"testMessage":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}';
const invalidAsyncAPI = { "asyncapi": "2.0.0", "info": {} };
const errorsOfInvalidAsyncAPI = [{keyword: 'required',dataPath: '.info',schemaPath: '#/required',params: { missingProperty: 'title' },message: 'should have required property \'title\''},{keyword: 'required',dataPath: '.info',schemaPath: '#/required',params: { missingProperty: 'version' },message: 'should have required property \'version\''},{keyword: 'required',dataPath: '',schemaPath: '#/required',params: { missingProperty: 'channels' },message: 'should have required property \'channels\''}];
const errorsOfInvalidAsyncAPI = [{ keyword: 'required', dataPath: '.info', schemaPath: '#/required', params: { missingProperty: 'title' }, message: 'should have required property \'title\'' }, { keyword: 'required', dataPath: '.info', schemaPath: '#/required', params: { missingProperty: 'version' }, message: 'should have required property \'version\'' }, { keyword: 'required', dataPath: '', schemaPath: '#/required', params: { missingProperty: 'channels' }, message: 'should have required property \'channels\'' }];

@@ -24,7 +24,7 @@ describe('parse()', function () {

});
it('should forward ajv errors and AsyncAPI json', async function () {
try {
await parser.parse(invalidAsyncAPI);
} catch(e) {
} catch (e) {
await expect(e.errors).to.deep.equal(errorsOfInvalidAsyncAPI);

@@ -34,7 +34,7 @@ await expect(e.parsedJSON).to.deep.equal(invalidAsyncAPI);

});
it('should not forward AsyncAPI json when it is not possible to convert it', async function () {
try {
await parser.parse('bad');
} catch(e) {
} catch (e) {
await expect(e.constructor.name).to.equal('ParserErrorNoJS');

@@ -48,3 +48,3 @@ await expect(e.parsedJSON).to.equal(undefined);

await parser.parse('bad: true');
} catch(e) {
} catch (e) {
await expect(e.constructor.name).to.equal('ParserErrorUnsupportedVersion');

@@ -54,3 +54,3 @@ await expect(e.parsedJSON).to.deep.equal({ bad: true });

});
it('should not apply traits', async function () {

@@ -60,3 +60,3 @@ const result = await parser.parse(inputYAML, { path: __filename, applyTraits: false });

});
it('should fail to resolve relative files when options.path is not provided', async function () {

@@ -67,3 +67,3 @@ const testFn = async () => await parser.parse(inputYAML);

});
it('should throw error if document is invalid YAML', async function () {

@@ -70,0 +70,0 @@ const testFn = async () => await parser.parse(invalidYAML, { path: __filename });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc