diff --git a/.sonarcloud.properties b/.sonarcloud.properties index 366aa6f5..5f8c8720 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -1,2 +1,2 @@ # Disable specific duplicate code since it would introduce more complexity to reduce it. -sonar.cpd.exclusions=src/standard.ts +sonar.cpd.exclusions=src/standards/v2.ts, src/standards/v3.ts, test/fixtures/main.fixtures.ts diff --git a/CODEOWNERS b/CODEOWNERS index bb3efa2e..697b4fb2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,4 +5,4 @@ # For more details, read the following article on GitHub: https://help.github.com/articles/about-codeowners/. # The default owners are automatically added as reviewers when you open a pull request unless different owners are specified in the file. -* @aayushmau5 @vinitshahdeo @onbit-uchenik @magicmatatjahu @derberg @asyncapi-bot-eve +* @aayushmau5 @magicmatatjahu @derberg @asyncapi-bot-eve diff --git a/src/helpers/DiffHelpers.ts b/src/helpers/DiffHelpers.ts index 6084f718..d30108cf 100644 --- a/src/helpers/DiffHelpers.ts +++ b/src/helpers/DiffHelpers.ts @@ -99,3 +99,20 @@ export function formatDiffOutput( } return output; } + +export function getDocumentMajorVersion(document: any): string { + const asyncapiVersion: string = document.asyncapi; + return asyncapiVersion.split('.')[0]; +} + +export function incompatibleDocuments( + firstDocument: any, + secondDocument: any +): boolean { + const firstDocumentMajorVersion = getDocumentMajorVersion(firstDocument); + const secondDocumentMajorVersion = getDocumentMajorVersion(secondDocument); + if (firstDocumentMajorVersion !== secondDocumentMajorVersion) { + return true; + } + return false; +} diff --git a/src/main.ts b/src/main.ts index 09082b0b..7b00cad8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,10 @@ import { Config, OverrideStandard } from './types'; import generateDiff from './generateDiff'; -import { standard } from './standard'; +import { getStandardFromVersion } from './standard'; import categorizeChanges from './categorizeChanges'; import AsyncAPIDiff from './asyncapidiff'; import { mergeStandard } from './mergeStandard'; +import { incompatibleDocuments } from './helpers/DiffHelpers'; /** * Generates diff between two AsyncAPI documents @@ -33,6 +34,12 @@ export function diff( secondDocument: any, config: Config = {} ): AsyncAPIDiff { + if (incompatibleDocuments(firstDocument, secondDocument)) { + throw new TypeError('diff between different AsyncAPI version is not allowed'); + } + + const standard = getStandardFromVersion(firstDocument); + if (config.override) { if (typeof config.override !== 'object') { throw new TypeError('Override data must be an object'); @@ -43,7 +50,7 @@ export function diff( const diffOutput = generateDiff(firstDocument, secondDocument); const output = categorizeChanges(standard as OverrideStandard, diffOutput); return new AsyncAPIDiff(JSON.stringify(output), { - outputType: config.outputType || 'json', - markdownSubtype: config.markdownSubtype || 'json' + outputType: config.outputType ?? 'json', + markdownSubtype: config.markdownSubtype ?? 'json', }); } diff --git a/src/standard.ts b/src/standard.ts index 14f3274b..f052f32e 100644 --- a/src/standard.ts +++ b/src/standard.ts @@ -1,749 +1,12 @@ -import { breaking, nonBreaking, unclassified } from './constants'; +import { getDocumentMajorVersion } from './helpers/DiffHelpers'; +import { standard as v2Standard } from './standards/v2'; +import { standard as v3Standard } from './standards/v3'; +import { StandardType } from 'types'; -/** - * The standard object - * - * @private - */ -export const standard = { - '/asyncapi': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/id': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/defaultContentType': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/info': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/info/version': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/info/termsOfService': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/info/license': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/info/license/name': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/info/license/url': { - add: breaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/title': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/contact': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/contact/name': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/contact/url': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/info/contact/email': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/servers': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/url': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/servers/*/protocol': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/protocolVersion': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables/*/enum': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables/*/enum/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables/*/default': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/variables/*/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/servers/*/variables/*/examples': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/servers/*/variables/*/examples/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/servers/*/security': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/security/*': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/servers/*/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/operationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/traits': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/traits/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/traits/operationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/traits/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/traits/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/traits/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/traits/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/traits/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/traits/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/message': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/headers': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/message/correlationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/correlationId/location': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/correlationId/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/schemaFormat': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/contentType': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/name': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/title': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/message/examples': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/examples/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/headers': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/message/traits/correlationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/correlationId/location': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/correlationId/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/schemaFormat': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/contentType': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/subscribe/message/traits/name': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/title': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/subscribe/message/traits/examples': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/traits/examples/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/subscribe/message/payload': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/operationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/traits': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/traits/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/traits/operationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/traits/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/traits/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/traits/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/traits/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/traits/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/traits/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/message': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/headers': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/message/correlationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/correlationId/location': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/correlationId/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/schemaFormat': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/contentType': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/name': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/title': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/message/examples': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/examples/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/headers': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/message/traits/correlationId': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/correlationId/location': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/correlationId/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/schemaFormat': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/contentType': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/publish/message/traits/name': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/title': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/summary': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/tags/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/bindings': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/publish/message/traits/examples': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/traits/examples/*': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/publish/message/payload': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/parameters': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/parameters/*': { - add: nonBreaking, - remove: breaking, - edit: breaking, - }, - '/channels/*/parameters/*/description': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/channels/*/parameters/*/schema': { - add: unclassified, - remove: unclassified, - edit: unclassified, - }, - '/channels/*/parameters/*/location': { - add: breaking, - remove: breaking, - edit: breaking, - }, - '/components': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/tags': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, - '/externalDocs': { - add: nonBreaking, - remove: nonBreaking, - edit: nonBreaking, - }, -}; +export function getStandardFromVersion(document: any): StandardType { + const majorVersion = getDocumentMajorVersion(document); + if (majorVersion === '2') { + return v2Standard; + } + return v3Standard; +} diff --git a/src/standards/v2.ts b/src/standards/v2.ts new file mode 100644 index 00000000..c59caa3c --- /dev/null +++ b/src/standards/v2.ts @@ -0,0 +1,749 @@ +import { breaking, nonBreaking, unclassified } from '../constants'; + +/** + * The standard object for AsyncAPI v2 + * + * @private + */ +export const standard = { + '/asyncapi': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/id': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/defaultContentType': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/info': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/version': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/termsOfService': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/license': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/license/name': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/info/license/url': { + add: breaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/contact': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/contact/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/contact/url': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/contact/email': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/url': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/protocol': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/protocolVersion': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/enum': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/enum/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/default': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/variables/*/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/variables/*/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/security': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/security/*': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/operationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/traits/operationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/traits/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/traits/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/traits/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/traits/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/traits/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/traits/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/message': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/headers': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/message/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/correlationId/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/correlationId/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/schemaFormat': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/contentType': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/message/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/headers': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/message/traits/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/correlationId/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/correlationId/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/schemaFormat': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/contentType': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/subscribe/message/traits/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/subscribe/message/traits/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/traits/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/subscribe/message/payload': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/operationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/traits/operationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/traits/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/traits/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/traits/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/traits/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/traits/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/traits/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/message': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/headers': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/message/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/correlationId/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/correlationId/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/schemaFormat': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/contentType': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/message/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/headers': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/message/traits/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/correlationId/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/correlationId/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/schemaFormat': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/contentType': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/publish/message/traits/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/publish/message/traits/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/traits/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/publish/message/payload': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/parameters': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/parameters/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/parameters/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/parameters/*/schema': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/parameters/*/location': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/components': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, +}; diff --git a/src/standards/v3.ts b/src/standards/v3.ts new file mode 100644 index 00000000..09a36c8d --- /dev/null +++ b/src/standards/v3.ts @@ -0,0 +1,609 @@ +import { breaking, nonBreaking, unclassified } from '../constants'; + +/** + * The standard object for AsyncAPI v3 + * + * @private + */ +export const standard = { + '/asyncapi': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/id': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/version': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/termsOfService': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/info/contact': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/contact/name': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/contact/url': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/contact/email': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/license': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/license/name': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/info/license/url': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/info/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/host': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/protocol': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/protocolVersion': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/pathname': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/variables': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/enum': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/enum/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/default': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/variables/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/variables/*/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/variables/*/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/security': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/security/*': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/servers/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/servers/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/defaultContentType': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/address': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/headers': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/payload': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/contentType': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/name': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/messages/*/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/traits/*/headers': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/messages/*/traits/*/correlationId': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/traits/*/correlationId/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/correlationId/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/traits/*/contentType': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/messages/*/traits/*/name': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/channels/*/messages/*/traits/*/examples': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/messages/*/traits/*/examples/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/servers': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/servers/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/parameters': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/channels/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/channels/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/operations': { + add: nonBreaking, + remove: breaking, + edit: nonBreaking, + }, + '/operations/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/action': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/channel': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/security': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/security/*': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/operations/*/traits': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/traits/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/traits/*/title': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/summary': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/security': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/traits/*/security/*': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/traits/*/tags': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/tags/*': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/externalDocs': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/traits/*/bindings': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/operations/*/messages': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/messages/*': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/reply': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/reply/address': { + add: breaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/reply/address/description': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + }, + '/operations/*/reply/address/location': { + add: nonBreaking, + remove: breaking, + edit: breaking, + }, + '/operations/*/reply/channel': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/operations/*/reply/messages': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/operations/*/reply/messages/*': { + add: unclassified, + remove: unclassified, + edit: unclassified, + }, + '/components': { + add: nonBreaking, + remove: nonBreaking, + edit: nonBreaking, + } +}; diff --git a/src/types.ts b/src/types.ts index 9bc778b8..3b1a1c07 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ import {ReplaceOperation, AddOperation} from 'fast-json-patch'; -import {standard} from './standard'; +import {standard as v2Standard} from './standards/v2'; +import {standard as v3Standard} from './standards/v3'; import {breaking, nonBreaking, unclassified} from './constants'; export type ActionType = 'add' | 'remove' | 'edit'; @@ -38,7 +39,7 @@ export type Output = JSONOutput | string; export type ValueOperation = ReplaceOperation | AddOperation; -export type StandardType = typeof standard; +export type StandardType = typeof v2Standard | typeof v3Standard; export interface OverrideObject { [key: string]: Classifier; diff --git a/test/fixtures/main.fixtures.ts b/test/fixtures/main.fixtures.ts index 6f0f120c..f96dcc7a 100644 --- a/test/fixtures/main.fixtures.ts +++ b/test/fixtures/main.fixtures.ts @@ -176,6 +176,102 @@ export const diffOutput = { ], }; +export const diffOutputV3 = { + changes: [ + { + action: 'edit', + after: '1.1', + before: '1.0', + path: '/components/operations/sendUserSignUp/channel/servers/0/protocolVersion', + type: 'unclassified', + }, + { + action: 'edit', + after: 'rabbitmq.in.mycompany.com:5673', + before: 'rabbitmq.in.mycompany.com:5672', + path: '/components/operations/sendUserSignUp/channel/servers/0/host', + type: 'unclassified', + }, + { + action: 'edit', + after: 'users.{userid}', + before: 'users.{userId}', + path: '/components/operations/sendUserSignUp/channel/address', + type: 'unclassified', + }, + { + action: 'edit', + after: '1.1', + before: '1.0', + path: '/operations/sendUserSignUp/channel/servers/0/protocolVersion', + type: 'unclassified', + }, + { + action: 'edit', + after: 'rabbitmq.in.mycompany.com:5673', + before: 'rabbitmq.in.mycompany.com:5672', + path: '/operations/sendUserSignUp/channel/servers/0/host', + type: 'unclassified', + }, + { + action: 'edit', + after: 'users.{userid}', + before: 'users.{userId}', + path: '/operations/sendUserSignUp/channel/address', + type: 'unclassified', + }, + { + action: 'edit', + after: 'A short description', + before: 'A longer description', + path: '/operations/sendUserSignUp/description', + type: 'non-breaking', + }, + { + action: 'edit', + after: '1.1', + before: '1.0', + path: '/channels/user/servers/0/protocolVersion', + type: 'unclassified', + }, + { + action: 'edit', + after: 'rabbitmq.in.mycompany.com:5673', + before: 'rabbitmq.in.mycompany.com:5672', + path: '/channels/user/servers/0/host', + type: 'unclassified', + }, + { + action: 'edit', + after: 'users.{userid}', + before: 'users.{userId}', + path: '/channels/user/address', + type: 'breaking', + }, + { + action: 'edit', + after: '1.1', + before: '1.0', + path: '/servers/production/protocolVersion', + type: 'breaking', + }, + { + action: 'edit', + after: 'rabbitmq.in.mycompany.com:5673', + before: 'rabbitmq.in.mycompany.com:5672', + path: '/servers/production/host', + type: 'breaking', + }, + { + action: 'edit', + after: 'World', + before: 'Hello', + path: '/info/contact/name', + type: 'non-breaking', + }, + ], +}; + export const overrides = { '/channels/*': { add: 'breaking', @@ -278,6 +374,7 @@ export const changesWithOverrides = { }; export const specDocument1 = { + asyncapi: '2.1.0', servers: { google: { variables: { @@ -290,6 +387,7 @@ export const specDocument1 = { }; export const specDocument2 = { + asyncapi: '2.1.0', servers: { google: { variables: { diff --git a/test/helpers/DiffHelpers.spec.ts b/test/helpers/DiffHelpers.spec.ts index 3ada4c0b..ca2e2204 100644 --- a/test/helpers/DiffHelpers.spec.ts +++ b/test/helpers/DiffHelpers.spec.ts @@ -5,6 +5,8 @@ import { getBeforeValue, setIndex, formatDiffOutput, + getDocumentMajorVersion, + incompatibleDocuments, } from '../../src/helpers/DiffHelpers'; import { DiffOutput } from '../../src/types'; import { @@ -76,3 +78,17 @@ describe('formatDiffOutput function', () => { ).toStrictEqual(diffEditOutput); }); }); + +describe('between different asyncapi version', () => { + test('should return correct asyncapi major version', () => { + expect(getDocumentMajorVersion({asyncapi: '3.0.0'})).toEqual('3'); + }); + + test('documents are incompatible', () => { + expect(incompatibleDocuments({asyncapi: '3.0.0'}, {asyncapi: '2.1.0'})).toBeTruthy(); + }); + + test('documents are compatible', () => { + expect(incompatibleDocuments({asyncapi: '3.0.0'}, {asyncapi: '3.0.0'})).toBeFalsy(); + }); +}); diff --git a/test/main.spec.ts b/test/main.spec.ts index 60638272..8c824d91 100644 --- a/test/main.spec.ts +++ b/test/main.spec.ts @@ -17,12 +17,13 @@ import { arrayChanges, YAMLArrayChanges, MarkdownArrayChanges, + diffOutputV3, } from './fixtures/main.fixtures'; const parser = new Parser(); describe('main function', () => { - test('runs the diff function', async () => { + test('runs the diff function for spec v2', async () => { const firstSpecDocument = readFileSync( resolve('./test/spec/asyncapi.yml'), 'utf-8' @@ -43,9 +44,48 @@ describe('main function', () => { expect(output.nonBreaking()).toEqual(nonBreakingChanges); }); + test('throws on incompatible documents', async () => { + const firstSpecDocument = readFileSync( + resolve('./test/spec/asyncapi.yml'), + 'utf-8' + ); + const secondSpecDocument = readFileSync( + resolve('./test/spec/asyncapi-v3.yml'), + 'utf-8' + ); + const firstDocument = await parser.parse(firstSpecDocument); + const secondDocument = await parser.parse(secondSpecDocument); + + expect(() => diff( + firstDocument.document?.json(), + secondDocument.document?.json() + )).toThrowError( + new TypeError('diff between different AsyncAPI version is not allowed') + ); + }); + + test('runs the diff function for spec v3', async () => { + const firstSpecDocument = readFileSync( + resolve('./test/spec/asyncapi-v3.yml'), + 'utf-8' + ); + const secondSpecDocument = readFileSync( + resolve('./test/spec/asyncapi-v3-diff.yml'), + 'utf-8' + ); + const firstDocument = await parser.parse(firstSpecDocument); + const secondDocument = await parser.parse(secondSpecDocument); + const output = diff( + firstDocument.document?.json(), + secondDocument.document?.json() + ); + expect(output).toBeInstanceOf(AsyncAPIDiff); + expect(output.getOutput()).toEqual(diffOutputV3); + }); + test('runs the diff function with empty spec', () => { - const firstSpec = {}; - const secondSpec = {}; + const firstSpec = {asyncapi: '2.1.0'}; + const secondSpec = {asyncapi: '2.1.0'}; expect(diff(firstSpec, secondSpec).getOutput()).toEqual({ changes: [], }); diff --git a/test/mergeStandard.spec.ts b/test/mergeStandard.spec.ts index bf4c689d..d819875f 100644 --- a/test/mergeStandard.spec.ts +++ b/test/mergeStandard.spec.ts @@ -1,6 +1,6 @@ import { mergeStandard } from '../src/mergeStandard'; import { OverrideObject } from '../src/types'; -import { standard } from '../src/standard'; +import { getStandardFromVersion } from '../src/standard'; import { newKey, @@ -12,16 +12,19 @@ import { describe('mergeStandard()', () => { test('with empty override object', () => { + const standard = getStandardFromVersion({asyncapi: '2.1.0'}); mergeStandard(standard, {}); expect(JSON.stringify(standard)).toBe(standardAsString); }); test('with new override key', () => { + const standard = getStandardFromVersion({asyncapi: '2.1.0'}); mergeStandard(standard, newKey as OverrideObject); expect(JSON.stringify(standard)).toBe(mergedStandardAsString); }); test('with exisiting override key', () => { + const standard = getStandardFromVersion({asyncapi: '2.1.0'}); mergeStandard(standard, exisitngKey as OverrideObject); expect(JSON.stringify(standard)).toBe(exisitingKeyStandard); }); diff --git a/test/spec/asyncapi-v3-diff.yml b/test/spec/asyncapi-v3-diff.yml new file mode 100644 index 00000000..e5df94b5 --- /dev/null +++ b/test/spec/asyncapi-v3-diff.yml @@ -0,0 +1,327 @@ +asyncapi: 3.0.0 +info: + title: My Event-Driven API + version: 1.0.0 + description: This API provides real-time event streaming capabilities. + termsOfService: https://example.com/terms-of-service + contact: + name: World + email: helloworld@asyncapi.com + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + tags: + - name: Events + description: APIs related to event streaming + - name: Authentication + description: APIs for authentication and authorization + externalDocs: + description: Additional documentation + url: https://example.com/docs +servers: + production: + host: rabbitmq.in.mycompany.com:5673 + pathname: /v1 + protocol: amqp + protocolVersion: "1.1" + description: Production RabbitMQ broker (uses the 'production' vhost). + title: Production Server + summary: Production environment server + security: + - type: http + scheme: bearer + tags: + - name: production + description: Production environment + externalDocs: + description: Additional documentation for the production server + url: https://example.com/docs/production + bindings: + amqp: + exchange: my-exchange + queue: my-queue + staging: + host: rabbitmq.in.mycompany.com:5672 + pathname: /v1 + protocol: amqp + protocolVersion: "1.0" + description: Staging RabbitMQ broker (uses the 'staging' vhost). + title: Staging Server + summary: Staging environment server + security: + - type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. + tags: + - name: staging + description: Staging environment + externalDocs: + description: Additional documentation for the staging server + url: https://example.com/docs/staging + bindings: + amqp: + exchange: my-exchange + queue: my-queue +channels: + user: + address: 'users.{userid}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignedUp' + userCompletedOrder: + $ref: '#/components/messages/userCompletedOrder' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/servers/production' + bindings: + amqp: + is: queue + queue: + exclusive: true + tags: + - name: user + description: User-related messages + externalDocs: + description: 'Find more info here' + url: 'https://example.com' + userSignupReply: + address: 'users.signup.reply' + description: Channel for user signup replies + messages: + userSignedUpReply: + summary: User signup reply message + payload: + type: object + properties: + status: + type: string + description: Status of the signup process + message: + type: string + description: Additional information + + +operations: + sendUserSignUp: + action: send + title: User sign up + summary: Action to sign a user up. + description: A short description + channel: + $ref: '#/channels/user' + security: + - type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + tags: + - name: user + - name: signup + - name: register + bindings: + amqp: + ack: false + messages: + - $ref: '#/channels/user/messages/userSignedUp' + reply: + address: + location: '$message.header#/replyTo' + channel: + $ref: '#/channels/userSignupReply' + messages: + - $ref: '#/channels/userSignupReply/messages/userSignedUpReply' + +components: + schemas: + Category: + type: object + properties: + id: + type: integer + format: int64 + AvroExample: + schemaFormat: application/vnd.apache.avro+json;version=1.9.0 + + servers: + development: + host: '{stage}.in.mycompany.com' + protocol: amqp + description: RabbitMQ broker + bindings: + $ref: '#/components/serverBindings/devAmqp' + variables: + stage: + $ref: '#/components/serverVariables/stage' + security: + - $ref: '#/components/securitySchemes/oauth' + + serverVariables: + stage: + default: demo + description: This value is assigned by the service provider in this example of 'mycompany.com' + + channels: + user: + address: 'users.{userId}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignUp' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/components/servers/development' + bindings: + $ref: '#/components/channelBindings/user' + tags: + - $ref: '#/components/tags/user' + externalDocs: + $ref: '#/components/externalDocs/infoDocs' + + messages: + userSignUp: + summary: Action to sign a user up. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: '#/components/schemas/Category' + correlationId: + $ref: '#/components/correlationIds/default' + bindings: + $ref: '#/components/messageBindings/user' + userSignedUp: + summary: User signed up event + contentType: application/json + payload: + type: object + properties: + userId: + type: string + description: The ID of the user + email: + type: string + description: The email of the user + userCompletedOrder: + summary: User completed order event + contentType: application/json + payload: + type: object + properties: + orderId: + type: string + description: The ID of the order + userId: + type: string + description: The ID of the user + amount: + type: number + description: The total amount of the order + + + parameters: + userId: + description: Id of the user. + + correlationIds: + default: + description: Default Correlation ID + location: $message.header#/correlationId + + operations: + sendUserSignUp: + action: send + title: User sign up + channel: + $ref: '#/channels/user' + bindings: + $ref: '#/components/operationBindings/sendUser' + traits: + - $ref: '#/components/operationTraits/binding' + reply: + $ref: '#/components/replies/signupReply' + + replies: + signupReply: + address: + $ref: '#/components/replyAddresses/signupReply' + channel: + $ref: '#/channels/userSignupReply' + + replyAddresses: + signupReply: + location: '$message.header#/replyTo' + + + securitySchemes: + oauth: + type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + + operationTraits: + binding: + bindings: + amqp: + ack: false + + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + + tags: + user: + name: user + description: User-related messages + + externalDocs: + infoDocs: + url: https://example.com/docs + description: 'Find more info here' + + serverBindings: + devAmqp: + amqp: + exchange: my-exchange + queue: my-queue + + channelBindings: + user: + amqp: + is: queue + queue: + exclusive: true + + operationBindings: + sendUser: + amqp: + ack: false + + messageBindings: + user: + amqp: + contentEncoding: gzip + messageType: 'user.signup' + bindingVersion: '0.3.0' diff --git a/test/spec/asyncapi-v3.yml b/test/spec/asyncapi-v3.yml new file mode 100644 index 00000000..6b904c22 --- /dev/null +++ b/test/spec/asyncapi-v3.yml @@ -0,0 +1,327 @@ +asyncapi: 3.0.0 +info: + title: My Event-Driven API + version: 1.0.0 + description: This API provides real-time event streaming capabilities. + termsOfService: https://example.com/terms-of-service + contact: + name: Hello + email: helloworld@asyncapi.com + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + tags: + - name: Events + description: APIs related to event streaming + - name: Authentication + description: APIs for authentication and authorization + externalDocs: + description: Additional documentation + url: https://example.com/docs +servers: + production: + host: rabbitmq.in.mycompany.com:5672 + pathname: /v1 + protocol: amqp + protocolVersion: "1.0" + description: Production RabbitMQ broker (uses the 'production' vhost). + title: Production Server + summary: Production environment server + security: + - type: http + scheme: bearer + tags: + - name: production + description: Production environment + externalDocs: + description: Additional documentation for the production server + url: https://example.com/docs/production + bindings: + amqp: + exchange: my-exchange + queue: my-queue + staging: + host: rabbitmq.in.mycompany.com:5672 + pathname: /v1 + protocol: amqp + protocolVersion: "1.0" + description: Staging RabbitMQ broker (uses the 'staging' vhost). + title: Staging Server + summary: Staging environment server + security: + - type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. + tags: + - name: staging + description: Staging environment + externalDocs: + description: Additional documentation for the staging server + url: https://example.com/docs/staging + bindings: + amqp: + exchange: my-exchange + queue: my-queue +channels: + user: + address: 'users.{userId}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignedUp' + userCompletedOrder: + $ref: '#/components/messages/userCompletedOrder' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/servers/production' + bindings: + amqp: + is: queue + queue: + exclusive: true + tags: + - name: user + description: User-related messages + externalDocs: + description: 'Find more info here' + url: 'https://example.com' + userSignupReply: + address: 'users.signup.reply' + description: Channel for user signup replies + messages: + userSignedUpReply: + summary: User signup reply message + payload: + type: object + properties: + status: + type: string + description: Status of the signup process + message: + type: string + description: Additional information + + +operations: + sendUserSignUp: + action: send + title: User sign up + summary: Action to sign a user up. + description: A longer description + channel: + $ref: '#/channels/user' + security: + - type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + tags: + - name: user + - name: signup + - name: register + bindings: + amqp: + ack: false + messages: + - $ref: '#/channels/user/messages/userSignedUp' + reply: + address: + location: '$message.header#/replyTo' + channel: + $ref: '#/channels/userSignupReply' + messages: + - $ref: '#/channels/userSignupReply/messages/userSignedUpReply' + +components: + schemas: + Category: + type: object + properties: + id: + type: integer + format: int64 + AvroExample: + schemaFormat: application/vnd.apache.avro+json;version=1.9.0 + + servers: + development: + host: '{stage}.in.mycompany.com' + protocol: amqp + description: RabbitMQ broker + bindings: + $ref: '#/components/serverBindings/devAmqp' + variables: + stage: + $ref: '#/components/serverVariables/stage' + security: + - $ref: '#/components/securitySchemes/oauth' + + serverVariables: + stage: + default: demo + description: This value is assigned by the service provider in this example of 'mycompany.com' + + channels: + user: + address: 'users.{userId}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignUp' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/components/servers/development' + bindings: + $ref: '#/components/channelBindings/user' + tags: + - $ref: '#/components/tags/user' + externalDocs: + $ref: '#/components/externalDocs/infoDocs' + + messages: + userSignUp: + summary: Action to sign a user up. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: '#/components/schemas/Category' + correlationId: + $ref: '#/components/correlationIds/default' + bindings: + $ref: '#/components/messageBindings/user' + userSignedUp: + summary: User signed up event + contentType: application/json + payload: + type: object + properties: + userId: + type: string + description: The ID of the user + email: + type: string + description: The email of the user + userCompletedOrder: + summary: User completed order event + contentType: application/json + payload: + type: object + properties: + orderId: + type: string + description: The ID of the order + userId: + type: string + description: The ID of the user + amount: + type: number + description: The total amount of the order + + + parameters: + userId: + description: Id of the user. + + correlationIds: + default: + description: Default Correlation ID + location: $message.header#/correlationId + + operations: + sendUserSignUp: + action: send + title: User sign up + channel: + $ref: '#/channels/user' + bindings: + $ref: '#/components/operationBindings/sendUser' + traits: + - $ref: '#/components/operationTraits/binding' + reply: + $ref: '#/components/replies/signupReply' + + replies: + signupReply: + address: + $ref: '#/components/replyAddresses/signupReply' + channel: + $ref: '#/channels/userSignupReply' + + replyAddresses: + signupReply: + location: '$message.header#/replyTo' + + + securitySchemes: + oauth: + type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + + operationTraits: + binding: + bindings: + amqp: + ack: false + + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + + tags: + user: + name: user + description: User-related messages + + externalDocs: + infoDocs: + url: https://example.com/docs + description: 'Find more info here' + + serverBindings: + devAmqp: + amqp: + exchange: my-exchange + queue: my-queue + + channelBindings: + user: + amqp: + is: queue + queue: + exclusive: true + + operationBindings: + sendUser: + amqp: + ack: false + + messageBindings: + user: + amqp: + contentEncoding: gzip + messageType: 'user.signup' + bindingVersion: '0.3.0'