asyncapi-react icon indicating copy to clipboard operation
asyncapi-react copied to clipboard

`unstringify` somehow corrupts the parsed document

Open char0n opened this issue 9 months ago • 3 comments

Describe the bug

unstringify somehow corrupts the parsed document and results in failing to render the AsyncApiReactComponent.

How to Reproduce

Dependencies versions:

    "@asyncapi/avro-schema-parser": "^3.0.3",
    "@asyncapi/openapi-schema-parser": "^3.0.4",
    "@asyncapi/parser": "^3.0.0-next-major-spec.2",
    "@asyncapi/react-component": "^1.0.0-next.54",

Fixture:

asyncapi: '2.6.0'
info:
  title: Streetlights Kafka API
  version: '1.0.0'
  description: |
    The Smartylighting Streetlights API allows you to remotely manage the city lights.

    ### Check out its awesome features:

    * Turn a specific streetlight on/off 🌃
    * Dim a specific streetlight 😎
    * Receive real-time information about environmental lighting conditions 📈
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0

servers:
  scram-connections:
    url: test.mykafkacluster.org:18092
    protocol: kafka-secure
    description: Test broker secured with scramSha256
    security:
      - saslScram: []
    tags:
      - name: "env:test-scram"
        description: "This environment is meant for running internal tests through scramSha256"
      - name: "kind:remote"
        description: "This server is a remote server. Not exposed by the application"
      - name: "visibility:private"
        description: "This resource is private and only available to certain users"
  mtls-connections:
    url: test.mykafkacluster.org:28092
    protocol: kafka-secure
    description: Test broker secured with X509
    security:
      - certs: []
    tags:
      - name: "env:test-mtls"
        description: "This environment is meant for running internal tests through mtls"
      - name: "kind:remote"
        description: "This server is a remote server. Not exposed by the application"
      - name: "visibility:private"
        description: "This resource is private and only available to certain users"

defaultContentType: application/json

channels:
  smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured:
    description: The topic on which measured values may be produced and consumed.
    parameters:
      streetlightId:
        $ref: '#/components/parameters/streetlightId'
    publish:
      summary: Inform about environmental lighting conditions of a particular streetlight.
      operationId: receiveLightMeasurement
      traits:
        - $ref: '#/components/operationTraits/kafka'
      message:
        $ref: '#/components/messages/lightMeasured'

  smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
    parameters:
      streetlightId:
        $ref: '#/components/parameters/streetlightId'
    subscribe:
      operationId: turnOn
      traits:
        - $ref: '#/components/operationTraits/kafka'
      message:
        $ref: '#/components/messages/turnOnOff'

  smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
    parameters:
      streetlightId:
        $ref: '#/components/parameters/streetlightId'
    subscribe:
      operationId: turnOff
      traits:
        - $ref: '#/components/operationTraits/kafka'
      message:
        $ref: '#/components/messages/turnOnOff'

  smartylighting.streetlights.1.0.action.{streetlightId}.dim:
    parameters:
      streetlightId:
        $ref: '#/components/parameters/streetlightId'
    subscribe:
      operationId: dimLight
      traits:
        - $ref: '#/components/operationTraits/kafka'
      message:
        $ref: '#/components/messages/dimLight'

components:
  messages:
    lightMeasured:
      name: lightMeasured
      title: Light measured
      summary: Inform about environmental lighting conditions of a particular streetlight.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/commonHeaders'
      payload:
        $ref: "#/components/schemas/lightMeasuredPayload"
    turnOnOff:
      name: turnOnOff
      title: Turn on/off
      summary: Command a particular streetlight to turn the lights on or off.
      traits:
        - $ref: '#/components/messageTraits/commonHeaders'
      payload:
        $ref: "#/components/schemas/turnOnOffPayload"
    dimLight:
      name: dimLight
      title: Dim light
      summary: Command a particular streetlight to dim the lights.
      traits:
        - $ref: '#/components/messageTraits/commonHeaders'
      payload:
        $ref: "#/components/schemas/dimLightPayload"

  schemas:
    lightMeasuredPayload:
      type: object
      properties:
        lumens:
          type: integer
          minimum: 0
          description: Light intensity measured in lumens.
        sentAt:
          $ref: "#/components/schemas/sentAt"
    turnOnOffPayload:
      type: object
      properties:
        command:
          type: string
          enum:
            - on
            - off
          description: Whether to turn on or off the light.
        sentAt:
          $ref: "#/components/schemas/sentAt"
    dimLightPayload:
      type: object
      properties:
        percentage:
          type: integer
          description: Percentage to which the light should be dimmed to.
          minimum: 0
          maximum: 100
        sentAt:
          $ref: "#/components/schemas/sentAt"
    sentAt:
      type: string
      format: date-time
      description: Date and time when the message was sent.

  securitySchemes:
    saslScram:
      type: scramSha256
      description: Provide your username and password for SASL/SCRAM authentication
    certs:
      type: X509
      description: Download the certificate files from service provider

  parameters:
    streetlightId:
      description: The ID of the streetlight.
      schema:
        type: string

  messageTraits:
    commonHeaders:
      headers:
        type: object
        properties:
          my-app-header:
            type: integer
            minimum: 0
            maximum: 100

  operationTraits:
    kafka:
      bindings:
        kafka:
          clientId:
            type: string
            enum: ['my-app-id']

Code that parses:

import { Parser, stringify, unstringify } from '@asyncapi/parser';
import { OpenAPISchemaParser } from '@asyncapi/openapi-schema-parser';
import { AvroSchemaParser } from '@asyncapi/avro-schema-parser';

const parser = new Parser();
parser.registerSchemaParser(OpenAPISchemaParser());
parser.registerSchemaParser(AvroSchemaParser());

const { document } = await parser.parse(content);
const strigified = stringify(document);
const unstrigified = unstringify(strigified);

Feeding to React component:

<AsyncApiReactComponent schema={unstrigified} />

This results in:

image

Expected behavior

I would expect that there is a true isomorphism between stringify and unstrigify and that following equation applies:

document == unstrigify(strigify(document))

char0n avatar Sep 19 '23 12:09 char0n

@char0n is it react component related?

const strigified = stringify(document);
const unstrigified = unstringify(strigified);

this is Parser related code 🤔 did you try to check what is the difference between document == unstrigify(strigify(document)) ? sounds like parser bug

derberg avatar Sep 28 '23 14:09 derberg

@char0n is it react component related?

I would say yes. After further detailed investigation I can confirm that isomorpism of stringification works well, here is a proof:

import { stringify, unstringify } from '@asyncapi/parser';

// content is fixture from https://github.com/asyncapi/asyncapi-react/issues/769#issue-1902895557
const { document } = await parser.parse(content);
const strigified = stringify(document);
const unstrigified = unstringify(strigified);

console.assert(strigified === stringify(unstrigified));

Now when I do following, we're just fine:

<AsyncApiReactComponent schema={document} />

But when I do following I see errors and renderer fails to render:

<AsyncApiReactComponent schema={unstrigified} />

errors


Apparently stringing and unstrigifing the AsyncAPIDocument instances, does something to it which prevents renderer to render it.

char0n avatar Oct 26 '23 08:10 char0n

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

github-actions[bot] avatar Feb 24 '24 00:02 github-actions[bot]