asyncapi / parser-js

AsyncAPI parser for Javascript (browser-compatible too).
Apache License 2.0
119 stars 97 forks source link

document.allSchemas() returns "duplicated" schemas #896

Closed smoya closed 11 months ago

smoya commented 12 months ago

Describe the bug

document.allSchemas() method returns duplicated schemas when a schema is referenced from a component. In order to compare if two schemas are equal, we compare against their JSON representation (object.json()).

I compared the JSON string between duplicated and the only thing that changes is the pointer: one refers to the component section, the other to the place where the reference is.

How to Reproduce

Given the following doc:

asyncapi: '2.6.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  user/signedup:
    subscribe:
      message:
        $ref: '#/components/messages/UserSignedUp'
components:
  messages:
    UserSignedUp:
      payload:
        type: object
        properties:
          displayName:
            type: string
            description: Name of the user
          email:
            type: string
            format: email
            description: Email of the user

Parse the document and print all schemas:

import { Parser, fromFile, SchemaInterface } from '@asyncapi/parser';

const parser = new Parser();
const parse = async () => {
    const { document } = await fromFile(parser, './asyncapi.yaml').parse();
    document?.allSchemas().forEach((schema: SchemaInterface) => {
      console.log(JSON.stringify(schema), '\n');
    });
};

parse();

This prints the following 6 schemas:

Open ```js {"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/channels/user~1signedup/subscribe/message/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ``` ```js {"_json":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"_meta":{"pointer":"/channels/user~1signedup/subscribe/message/payload/properties/displayName","parent":{"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/channels/user~1signedup/subscribe/message/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}},"asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ``` ```js {"_json":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""},"_meta":{"pointer":"/channels/user~1signedup/subscribe/message/payload/properties/email","parent":{"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/channels/user~1signedup/subscribe/message/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}},"asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ``` ```js {"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/components/messages/UserSignedUp/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ``` ```js {"_json":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"_meta":{"pointer":"/components/messages/UserSignedUp/payload/properties/displayName","parent":{"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/components/messages/UserSignedUp/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}},"asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ``` ```js {"_json":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""},"_meta":{"pointer":"/components/messages/UserSignedUp/payload/properties/email","parent":{"_json":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"_meta":{"pointer":"/components/messages/UserSignedUp/payload","asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}},"asyncapi":{"source":"./asyncapi.yaml","input":"# asyncapi: '3.0.0'\n# info:\n# title: Account Service\n# version: 1.0.0\n# description: This service is in charge of processing user signups\n# channels:\n# test: {}\n \n# operations:\n# user/signedup:\n# action: send\n# channel: \n# $ref: '#/channels/test'\n# messages:\n# - $ref: '#/components/messages/UserSignedUp'\n# components:\n# messages:\n# UserSignedUp:\n# payload:\n# type: object\n# properties:\n# displayName:\n# type: string\n# description: Name of the user\n# email:\n# type: string\n# format: email\n# description: Email of the user\n\nasyncapi: '2.6.0'\ninfo:\n title: Account Service\n version: 1.0.0\n description: This service is in charge of processing user signups\nchannels:\n user/signedup:\n subscribe:\n message:\n $ref: '#/components/messages/UserSignedUp'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n displayName:\n type: string\n description: Name of the user\n email:\n type: string\n format: email\n description: Email of the user\n\n","parsed":{"asyncapi":"2.6.0","info":{"title":"Account Service","version":"1.0.0","description":"This service is in charge of processing user signups"},"channels":{"user/signedup":{"subscribe":{"message":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}}},"components":{"messages":{"UserSignedUp":{"payload":{"type":"object","properties":{"displayName":{"type":"string","description":"Name of the user","x-parser-schema-id":""},"email":{"type":"string","format":"email","description":"Email of the user","x-parser-schema-id":""}},"x-parser-schema-id":""},"x-parser-message-name":"UserSignedUp"}}},"x-parser-spec-parsed":true,"x-parser-api-version":3},"semver":{"version":"2.6.0","major":2,"minor":6,"patch":0}}}} ```

The issue seems to be the pointer field, which differs from /components/messages/UserSignedUp/... and /channels/user~1signedup/subscribe/message/...`

Shall we skip pointer field when comparing perhaps?

Expected behavior

Schemas should not be duplicated, as in v3. As per the example, only 3 schemas should be returned.

jonaslagoni commented 12 months ago

However, if we use the parser under next-major-spec branch so we parse v3 docs, it does not happen:

That example is technically an invalid v3 document as the channel does not contain the messages being references in the operation. If you add the messages to the v3 doc, does that re-create the problem as in v2?

smoya commented 12 months ago

However, if we use the parser under next-major-spec branch so we parse v3 docs, it does not happen:

That example is technically an invalid v3 document as the channel does not contain the messages being references in the operation. If you add the messages to the v3 doc, does that re-create the problem as in v2?

Yes, I was about to write it right now. Same issue happens with v3 as well. And it's about the pointer.

asyncapi: '3.0.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  UserSignedUp: 
    messages:
      UserSignedUp:
        $ref: '#/components/messages/UserSignedUp'
operations:
  user/signedup:
    action: send
    channel: 
      $ref: '#/channels/UserSignedUp'
    messages:
      - $ref: '#/components/messages/UserSignedUp'
components:
  messages:
    UserSignedUp:
      payload:
        type: object
        properties:
          displayName:
            type: string
            description: Name of the user
          email:
            type: string
            format: email
            description: Email of the user
smoya commented 12 months ago

Updated description according to previous comment

derberg commented 11 months ago

but your v3 example is not valid either, right?

valid is:

asyncapi: '3.0.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  UserSignedUp: 
    messages:
      UserSignedUp:
        $ref: '#/components/messages/UserSignedUp'
operations:
  user/signedup:
    action: send
    channel: 
      $ref: '#/channels/UserSignedUp'
    messages:
      - $ref: '#/channels/UserSignedUp/messages/UserSignedUp'
components:
  messages:
    UserSignedUp:
      payload:
        type: object
        properties:
          displayName:
            type: string
            description: Name of the user
          email:
            type: string
            format: email
            description: Email of the user

so you should reference message from a channel, not components. How else will you validate if message referenced from the operation it the same as in the channel? especially that you need to validate the messageId as well, right?

derberg commented 11 months ago

let's take

asyncapi: '2.6.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  user/signedup:
    subscribe:
      message:
        $ref: '#/components/messages/UserSignedUp'
components:
  messages:
    UserSignedUp:
      payload:
        type: object
        properties:
          displayName:
            type: string
            description: Name of the user
          email:
            type: string
            format: email
            description: Email of the user

and converter creates

asyncapi: 3.0.0
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  user/signedup:
    address: user/signedup
    messages:
      subscribe.message:
        $ref: '#/components/messages/UserSignedUp'
operations:
  user/signedup.subscribe:
    action: send
    channel:
      $ref: '#/channels/user~1signedup'
    messages:
      - $ref: '#/components/messages/UserSignedUp'
components:
  messages:
    UserSignedUp:
      payload:
        type: object
        properties:
          displayName:
            type: string
            description: Name of the user
          email:
            type: string
            format: email
            description: Email of the user

it is invalid document

    messages:
      - $ref: '#/components/messages/UserSignedUp'

is not the same as

messages:
      subscribe.message:
        $ref: '#/components/messages/UserSignedUp'

the id do not match

smoya commented 11 months ago

Whatever you use, it doesn't really matter. The issue keeps happening because the ID of those objects are not used for comparing but the .json() object of those.

BTW, I just found the bug. This is the callback we use for comparing:

const schemas: Set<SchemaInterface> = new Set();
    function callback(schema: SchemaInterface) {
      if (!schemas.has(schema.json())) {
        schemas.add(schema);
      }
    }

Source: https://github.com/asyncapi/parser-js/blob/next-major-spec/src/models/v3/asyncapi.ts#L149-L154 (same for v2 model as well)

Note that we check if the schema.json() is already present in the set, however we never store the output of .json() on it but the Schema. Meaning if (!schemas.has(schema.json())) { is always true.

smoya commented 11 months ago

Here is the fix https://github.com/asyncapi/parser-js/pull/897

cc @derberg @jonaslagoni

smoya commented 11 months ago

Fixed by https://github.com/asyncapi/parser-js/pull/897