Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

feat: initial structure+first approach #3

7 changes: 7 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
local
.vscode
.idea
coverage
*.DS_Store
109 changes: 109 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
env:
node: true
es6: true
mocha: true

plugins:
- sonarjs
- mocha
- security

extends:
- plugin:sonarjs/recommended
- plugin:mocha/recommended
- plugin:security/recommended

parserOptions:
ecmaVersion: 2018

rules:
# Ignore Rules
strict: 0
no-underscore-dangle: 0
no-mixed-requires: 0
no-process-exit: 0
no-warning-comments: 0
curly: 0
no-multi-spaces: 0
no-alert: 0
consistent-return: 0
consistent-this: [0, self]
func-style: 0
max-nested-callbacks: 0
camelcase: 0

# Warnings
no-debugger: 1
no-empty: 1
no-invalid-regexp: 1
no-unused-expressions: 1
no-native-reassign: 1
no-fallthrough: 1
sonarjs/cognitive-complexity: 1

# Errors
eqeqeq: 2
no-undef: 2
no-dupe-keys: 2
no-empty-character-class: 2
no-self-compare: 2
valid-typeof: 2
no-unused-vars: [2, { "args": "none" }]
handle-callback-err: 2
no-shadow-restricted-names: 2
no-new-require: 2
no-mixed-spaces-and-tabs: 2
block-scoped-var: 2
no-else-return: 2
no-throw-literal: 2
no-void: 2
radix: 2
wrap-iife: [2, outside]
no-shadow: 0
no-use-before-define: [2, nofunc]
no-path-concat: 2
valid-jsdoc: [0, {requireReturn: false, requireParamDescription: false, requireReturnDescription: false}]

# stylistic errors
no-spaced-func: 2
semi-spacing: 2
quotes: [2, 'single']
key-spacing: [2, { beforeColon: false, afterColon: true }]
indent: [2, 2]
no-lonely-if: 2
no-floating-decimal: 2
brace-style: [2, 1tbs, { allowSingleLine: true }]
comma-style: [2, last]
no-multiple-empty-lines: [2, {max: 1}]
no-nested-ternary: 2
operator-assignment: [2, always]
padded-blocks: [2, never]
quote-props: [2, as-needed]
keyword-spacing: [2, {'before': true, 'after': true, 'overrides': {}}]
space-before-blocks: [2, always]
array-bracket-spacing: [2, never]
computed-property-spacing: [2, never]
space-in-parens: [2, never]
space-unary-ops: [2, {words: true, nonwords: false}]
wrap-regex: 2
linebreak-style: 0
semi: [2, always]
arrow-spacing: [2, {before: true, after: true}]
no-class-assign: 2
no-const-assign: 2
no-dupe-class-members: 2
no-this-before-super: 2
no-var: 2
object-shorthand: [2, always]
prefer-arrow-callback: 2
prefer-const: 2
prefer-spread: 2
prefer-template: 2

overrides:
- files: "test/**"
rules:
prefer-arrow-callback: 0
sonarjs/no-duplicate-string: 0
security/detect-object-injection: 0
security/detect-non-literal-fs-filename: 0
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/node_modules/
dist
local
.vscode
.idea
coverage
*.DS_Store
74 changes: 74 additions & 0 deletions lib/appRelationsDiscovery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const {validate} = require('./utils');

const supportedSyntax = ['default','mermaid'];

const defaultOptions = {
syntax: 'default',
};

/**
* Validates and analyzes a list of AsyncAPI documents and get applications described by those files
*
* @param {Array} asyncApiDocs An array of asyncApiDocuments
* @param {Object} options for getting a relations
* @returns {Promise<DiscoveredRelations>} Relations between documents
*/
// eslint-disable-next-line sonarjs/cognitive-complexity
async function getRelations(asyncApiDocs, { syntax } = defaultOptions) {
if (!Array.isArray(asyncApiDocs)) throw new Error('You must pass an array of AsyncApiDocuments on which you wish to discover the relations between');
if (!supportedSyntax.includes(syntax)) throw new Error('The given syntax is not supported');

let parsedAsyncApiDocs;
try {
parsedAsyncApiDocs = await validate(asyncApiDocs);
} catch (e) {
throw new Error(e);
}
const metrics = new Map();

parsedAsyncApiDocs.forEach(doc => {
if (doc.hasServers()) {
const servers = doc.servers();

for (const credentials of Object.values(servers)) {
const slug = `${credentials.url()},${credentials.protocol()}`;
let relation;
if (metrics.has(slug)) {
relation = metrics.get(slug);
} else {
relation = new Map();
arjungarg07 marked this conversation as resolved.
Show resolved Hide resolved
metrics.set(slug,relation);
}

if (doc.hasChannels()) {
doc.channelNames().forEach((channelName) => {
let application;
if (relation.has(channelName)) {
application = relation.get(channelName);
} else {
application = {
sub: [],
pub: [],
};
arjungarg07 marked this conversation as resolved.
Show resolved Hide resolved
relation.set(channelName, application);
}

const channel = doc.channel(channelName);
const title = doc.info().title();

if (channel.hasPublish()) {
application.pub.push(title);
}
if (channel.hasSubscribe()) {
application.sub.push(title);
}
});
}
};
}
});
if (syntax === 'default')
return metrics;
};

module.exports = {getRelations};
3 changes: 3 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const appRelationsDiscovery = require('./appRelationsDiscovery');

module.exports = appRelationsDiscovery;
13 changes: 13 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const parser = require('@asyncapi/parser');

/**
* Validate and parse given array of AsyncAPI documents.
*
* @param {Array} asyncApiDocs unparsed AsyncAPI documents
* @returns {Array} parsed AsyncAPI documents
*/
function validate(asyncApiDocs) {
arjungarg07 marked this conversation as resolved.
Show resolved Hide resolved
return Promise.all(asyncApiDocs.map(async doc => parser.parse(doc.json())));
}

module.exports = { validate };
Loading