From b569a35426294003b7d12e91fb7c908e38d22c67 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Tue, 14 Nov 2023 21:53:10 +0100 Subject: [PATCH 1/6] fix: doc.allSchemas() skips now duplicates (#897) --- src/models/utils.ts | 25 +++++++++++++++++++++++++ src/models/v2/asyncapi.ts | 23 +++-------------------- src/models/v3/asyncapi.ts | 32 ++++++++------------------------ test/models/v2/asyncapi.spec.ts | 8 ++++++++ test/models/v3/asyncapi.spec.ts | 7 +++++++ 5 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/models/utils.ts b/src/models/utils.ts index 298a4dde0..ced726791 100644 --- a/src/models/utils.ts +++ b/src/models/utils.ts @@ -1,5 +1,9 @@ import type { BaseModel, ModelMetadata } from './base'; import type { DetailedAsyncAPI } from '../types'; +import { SchemaInterface } from './schema'; +import { SchemaTypesToIterate, traverseAsyncApiDocument } from '../iterator'; +import { AsyncAPIDocumentInterface } from './asyncapi'; +import { SchemasInterface } from 'models'; export interface Constructor extends Function { new (...any: any[]): T; @@ -12,3 +16,24 @@ export type InferModelMetadata = T extends BaseModel ? M : export function createModel(Model: Constructor, value: InferModelData, meta: Omit & { asyncapi?: DetailedAsyncAPI } & InferModelMetadata, parent?: BaseModel): T { return new Model(value, { ...meta, asyncapi: meta.asyncapi || parent?.meta().asyncapi }); } + +export function schemasFromDocument(document: AsyncAPIDocumentInterface, SchemasModel: Constructor, includeComponents: boolean): T { + const jsonInstances: Set = new Set(); + const schemas: Set = new Set(); + + function callback(schema: SchemaInterface) { + // comparing the reference (and not just the value) to the .json() object + if (!jsonInstances.has(schema.json())) { + jsonInstances.add(schema.json()); + schemas.add(schema); // unique schemas + } + } + + let toIterate = Object.values(SchemaTypesToIterate); + if (!includeComponents) { + toIterate = toIterate.filter(s => s !== SchemaTypesToIterate.Components); + } + traverseAsyncApiDocument(document, callback, toIterate); + + return new SchemasModel(Array.from(schemas)); +} diff --git a/src/models/v2/asyncapi.ts b/src/models/v2/asyncapi.ts index c7329c1b6..5cd0e8cbd 100644 --- a/src/models/v2/asyncapi.ts +++ b/src/models/v2/asyncapi.ts @@ -12,8 +12,8 @@ import { SecurityScheme } from './security-scheme'; import { Schemas } from './schemas'; import { extensions } from './mixins'; -import { traverseAsyncApiDocument, SchemaTypesToIterate } from '../../iterator'; import { tilde } from '../../utils'; +import { schemasFromDocument } from '../utils'; import type { AsyncAPIDocumentInterface } from '../asyncapi'; import type { InfoInterface } from '../info'; @@ -27,7 +27,6 @@ import type { OperationInterface } from '../operation'; import type { MessagesInterface } from '../messages'; import type { MessageInterface } from '../message'; import type { SchemasInterface } from '../schemas'; -import type { SchemaInterface } from '../schema'; import type { SecuritySchemesInterface } from '../security-schemes'; import type { ExtensionsInterface } from '../extensions'; @@ -81,7 +80,7 @@ export class AsyncAPIDocument extends BaseModel implements As } schemas(): SchemasInterface { - return this.__schemas(false); + return schemasFromDocument(this, Schemas, false); } securitySchemes(): SecuritySchemesInterface { @@ -130,26 +129,10 @@ export class AsyncAPIDocument extends BaseModel implements As } allSchemas(): SchemasInterface { - return this.__schemas(true); + return schemasFromDocument(this, Schemas, true); } extensions(): ExtensionsInterface { return extensions(this); } - - private __schemas(withComponents: boolean) { - const schemas: Set = new Set(); - function callback(schema: SchemaInterface) { - if (!schemas.has(schema.json())) { - schemas.add(schema); - } - } - - let toIterate = Object.values(SchemaTypesToIterate); - if (!withComponents) { - toIterate = toIterate.filter(s => s !== SchemaTypesToIterate.Components); - } - traverseAsyncApiDocument(this, callback, toIterate); - return new Schemas(Array.from(schemas)); - } } diff --git a/src/models/v3/asyncapi.ts b/src/models/v3/asyncapi.ts index 671616690..756140b0b 100644 --- a/src/models/v3/asyncapi.ts +++ b/src/models/v3/asyncapi.ts @@ -14,7 +14,7 @@ import { Schemas } from './schemas'; import { extensions } from './mixins'; import { tilde } from '../../utils'; -import { SchemaTypesToIterate, traverseAsyncApiDocument } from '../../iterator'; +import { schemasFromDocument } from '../utils'; import type { AsyncAPIDocumentInterface } from '../asyncapi'; import type { InfoInterface } from '../info'; @@ -26,12 +26,12 @@ import type { MessageInterface } from '../message'; import type { ComponentsInterface } from '../components'; import type { SecuritySchemesInterface } from '../security-schemes'; import type { ExtensionsInterface } from '../extensions'; -import type { SchemaInterface } from '../schema'; import type { SchemasInterface } from '../schemas'; +import type { OperationInterface } from '../operation'; +import type { ChannelInterface } from '../channel'; +import type { ServerInterface } from '../server'; + import type { v3 } from '../../spec-types'; -import { OperationInterface } from '../operation'; -import { ChannelInterface } from '../channel'; -import { ServerInterface } from '../server'; export class AsyncAPIDocument extends BaseModel implements AsyncAPIDocumentInterface { version(): string { @@ -89,8 +89,8 @@ export class AsyncAPIDocument extends BaseModel implements As return new Messages(messages); } - schemas() { - return this.__schemas(false); + schemas(): SchemasInterface { + return schemasFromDocument(this, Schemas, false); } securitySchemes(): SecuritySchemesInterface { @@ -138,26 +138,10 @@ export class AsyncAPIDocument extends BaseModel implements As } allSchemas(): SchemasInterface { - return this.__schemas(true); + return schemasFromDocument(this, Schemas, true); } extensions(): ExtensionsInterface { return extensions(this); } - - private __schemas(withComponents: boolean) { - const schemas: Set = new Set(); - function callback(schema: SchemaInterface) { - if (!schemas.has(schema.json())) { - schemas.add(schema); - } - } - - let toIterate = Object.values(SchemaTypesToIterate); - if (!withComponents) { - toIterate = toIterate.filter(s => s !== SchemaTypesToIterate.Components); - } - traverseAsyncApiDocument(this, callback, toIterate); - return new Schemas(Array.from(schemas)); - } } diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index 7f89795ae..3b5146ca9 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -308,6 +308,14 @@ describe('AsyncAPIDocument model', function() { const d = new AsyncAPIDocument(doc); expect(d.allSchemas()).toBeInstanceOf(Schemas); }); + + it('should return a collection of schemas (with schemas from components) without duplicates', function() { + const sharedMessage = { payload: {} }; + const doc = serializeInput({ channels: { 'user/signup': { publish: { message: sharedMessage }, subscribe: { message: { oneOf: [{ payload: {} }, {}] } } }, 'user/logout': { publish: { message: { payload: {} } } } }, components: { messages: { aMessage: sharedMessage } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allSchemas()).toBeInstanceOf(Schemas); + expect(d.allSchemas()).toHaveLength(3); + }); }); describe('mixins', function() { diff --git a/test/models/v3/asyncapi.spec.ts b/test/models/v3/asyncapi.spec.ts index c326796cc..85e28e371 100644 --- a/test/models/v3/asyncapi.spec.ts +++ b/test/models/v3/asyncapi.spec.ts @@ -213,6 +213,13 @@ describe('AsyncAPIDocument model', function() { const d = new AsyncAPIDocument(doc); expect(d.allSchemas()).toBeInstanceOf(Schemas); }); + it('should return a collection of schemas (with schemas from components) without duplicates', function() { + const sharedMessage = { payload: {} }; + const doc = serializeInput({ channels: { userSignup: { address: 'user/signup', messages: { someMessage1: { payload: {}}, someMessage2: sharedMessage } } }, components: { messages: { aMessage: sharedMessage } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allSchemas()).toBeInstanceOf(Schemas); + expect(d.allSchemas()).toHaveLength(2); + }); }); describe('.allServers()', function() { From b3d900555db8effce29563e240f2a189244acfa4 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 14 Nov 2023 22:06:25 +0100 Subject: [PATCH 2/6] chore(release): v3.0.0-next-major-spec.10 (#898) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 245480462..1bafc7aa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.9", + "version": "3.0.0-next-major-spec.10", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.9", + "version": "3.0.0-next-major-spec.10", "license": "Apache-2.0", "dependencies": { "@asyncapi/specs": "^6.0.0-next-major-spec.9", diff --git a/package.json b/package.json index 9105a10b0..4121eaccf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.9", + "version": "3.0.0-next-major-spec.10", "description": "JavaScript AsyncAPI parser.", "bugs": { "url": "https://github.com/asyncapi/parser-js/issues" From 0e636a34f144ab97ae12ff26eaf87b66c2699dd0 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Thu, 16 Nov 2023 10:54:59 -1000 Subject: [PATCH 3/6] fix: wrong parserAPI number being checked (#902) --- src/document.ts | 4 ++-- test/document.spec.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/document.ts b/src/document.ts index b202b1c6a..76b0f257d 100644 --- a/src/document.ts +++ b/src/document.ts @@ -1,4 +1,4 @@ -import { AsyncAPIDocumentV2, AsyncAPIDocumentV3 } from './models'; +import { AsyncAPIDocumentV2, AsyncAPIDocumentV3, ParserAPIVersion } from './models'; import { unstringify } from './stringify'; import { createDetailedAsyncAPI } from './utils'; @@ -43,7 +43,7 @@ export function isAsyncAPIDocument(maybeDoc: unknown): maybeDoc is AsyncAPIDocum } if (maybeDoc && typeof (maybeDoc as AsyncAPIDocumentInterface).json === 'function') { const versionOfParserAPI = (maybeDoc as AsyncAPIDocumentInterface).json()[xParserApiVersion]; - return versionOfParserAPI === 2; + return versionOfParserAPI === ParserAPIVersion; } return false; } diff --git a/test/document.spec.ts b/test/document.spec.ts index dfa07761d..c9fb0e5c0 100644 --- a/test/document.spec.ts +++ b/test/document.spec.ts @@ -114,8 +114,12 @@ describe('utils', function() { expect(isAsyncAPIDocument(createAsyncAPIDocument(detailed))).toEqual(true); }); - it('document with the x-parser-api-version extension set to 2 should be AsyncAPI document', async function() { - expect(isAsyncAPIDocument({ json() { return { [xParserApiVersion]: 2 }; } })).toEqual(true); + it('document with the x-parser-api-version extension set to 3 should be AsyncAPI document', async function() { + expect(isAsyncAPIDocument({ json() { return { [xParserApiVersion]: 3 }; } })).toEqual(true); + }); + + it('document with the x-parser-api-version extension set to 2 should not be AsyncAPI document', async function() { + expect(isAsyncAPIDocument({ json() { return { [xParserApiVersion]: 2 }; } })).toEqual(false); }); it('document with the x-parser-api-version extension set to 1 should not be AsyncAPI document', async function() { From 8be69753add635f62ddee7b1c4b738424a00aa90 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 16 Nov 2023 22:04:28 +0100 Subject: [PATCH 4/6] chore(release): v3.0.0-next-major-spec.11 (#903) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bafc7aa7..6b509c8ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.10", + "version": "3.0.0-next-major-spec.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.10", + "version": "3.0.0-next-major-spec.11", "license": "Apache-2.0", "dependencies": { "@asyncapi/specs": "^6.0.0-next-major-spec.9", diff --git a/package.json b/package.json index 4121eaccf..7705b2b5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.10", + "version": "3.0.0-next-major-spec.11", "description": "JavaScript AsyncAPI parser.", "bugs": { "url": "https://github.com/asyncapi/parser-js/issues" From 0ad2ec84fcc48a9bb25a65ef7a8f4419503108f3 Mon Sep 17 00:00:00 2001 From: Khuda Dad Nomani <32505158+KhudaDad414@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:04:54 +0000 Subject: [PATCH 5/6] fix: fix import statement (#908) --- src/models/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/utils.ts b/src/models/utils.ts index ced726791..47a0a73a7 100644 --- a/src/models/utils.ts +++ b/src/models/utils.ts @@ -3,10 +3,10 @@ import type { DetailedAsyncAPI } from '../types'; import { SchemaInterface } from './schema'; import { SchemaTypesToIterate, traverseAsyncApiDocument } from '../iterator'; import { AsyncAPIDocumentInterface } from './asyncapi'; -import { SchemasInterface } from 'models'; +import { SchemasInterface } from '../models'; export interface Constructor extends Function { - new (...any: any[]): T; + new(...any: any[]): T; } export type InferModelData = T extends BaseModel ? J : never; @@ -23,7 +23,7 @@ export function schemasFromDocument(document: AsyncA function callback(schema: SchemaInterface) { // comparing the reference (and not just the value) to the .json() object - if (!jsonInstances.has(schema.json())) { + if (!jsonInstances.has(schema.json())) { jsonInstances.add(schema.json()); schemas.add(schema); // unique schemas } From 4345060738cce07f22e18379b05eef6adde70949 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Mon, 20 Nov 2023 13:14:14 +0100 Subject: [PATCH 6/6] chore(release): v3.0.0-next-major-spec.12 (#909) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b509c8ea..97bde9702 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.11", + "version": "3.0.0-next-major-spec.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.11", + "version": "3.0.0-next-major-spec.12", "license": "Apache-2.0", "dependencies": { "@asyncapi/specs": "^6.0.0-next-major-spec.9", diff --git a/package.json b/package.json index 7705b2b5a..f0ccfad78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/parser", - "version": "3.0.0-next-major-spec.11", + "version": "3.0.0-next-major-spec.12", "description": "JavaScript AsyncAPI parser.", "bugs": { "url": "https://github.com/asyncapi/parser-js/issues"