Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive shapes and manual traverse on raw model #1816

Closed
1 of 4 tasks
deiteris opened this issue Jun 25, 2023 · 3 comments
Closed
1 of 4 tasks

Recursive shapes and manual traverse on raw model #1816

deiteris opened this issue Jun 25, 2023 · 3 comments

Comments

@deiteris
Copy link

deiteris commented Jun 25, 2023

Your issue may already be reported! Please search on Github issues before creating one.

  • I'm submitting a ...

    • bug report
    • feature request
    • question
    • other
  • What is the current behavior?

As far as I understand, AMF already has a built-in way to detect shape recursion. However, is there a specific shape type or method exposed to external users that are utilizing non-transformed model? I saw that there's RecursiveShape type, but none of my shapes seem to be detected as recursive (unless it applies on some transformation stage, but I want raw model specifically).

The sample code I try to use and that falls into infinite loop:

import amf, { ArrayShape, Module, NodeShape, PropertyShape, Shape, TypeIRI, TypeUtil } from "amf-client-js"

const raml = `
#%RAML 1.0 Library

types:
  OtherType:
    type: object
    properties:
      NestedField?: OtherType
      Children:
        type: array
        items:
          type: OtherType
`;

(async () => {
  const client = amf.RAMLConfiguration.RAML10().baseUnitClient()

  const data = (await client.parseContent(raml)).baseUnit as Module

  function traverse(type: Shape) {
    if (type.isLink) {
      type = type.linkTarget as Shape
    }

    // Doesn't do anything
    if (TypeUtil.isTypeOf(type, TypeIRI.RecursiveShape)) {
      console.log('Is recursive')
      return
    }

    if (TypeUtil.isTypeOf(type, TypeIRI.NodeShape)) {
      console.log('Is object')
      for (const property of (type as NodeShape).properties) {
        traverse(property)
      }
    } else if (TypeUtil.isTypeOf(type, TypeIRI.ArrayShape)) {
      console.log('Is array')
      const arrayType = type as ArrayShape
      if (arrayType.items) {
        traverse(arrayType.items)
      }
    } else if (TypeUtil.isTypeOf(type, TypeIRI.PropertyShape)) {
      console.log('Is property')
      traverse((type as PropertyShape).range)
    }
  }

  for (const type of data.declares as Shape[]) {
    traverse(type)
  }
})()
  • Please tell us about your environment:

    • AMF Version: 5.4.0-1
    • AMF Distribution: JS
    • Operating System: Windows 10 22H2
@nschejtman
Copy link
Contributor

Hi @deiteris

unless it applies on some transformation stage

That is exactly what we do.

If you are using the raw model not only you won't get RecursiveShapes but you might also get links. Some reference we can resolve during parsing but others will be parsed as links that should be resolved in transformation.

Not sure what is your use case but you can consider having a custom pipeline that handles just the things you need

@deiteris
Copy link
Author

deiteris commented Jun 25, 2023

Hi @nschejtman. I see... My use case is a custom renderer from RAML, so I only need to read the model. Probably would be nice if I could have a custom pipeline step to detect and make such RecursiveShape before my custom code (in fact, I've already done recursion detection so I check them as I traverse). But is it possible to do in Javascript already? I see the documentation mentions that it's only for Scala and Java.

@tomsfernandez
Copy link
Contributor

Hi @deiteris, unfortunately it is only for Scala and Java at the moment. You can create an issue as an enhancement request if you want. I don't know if we will be able to give it priority but at least it will be created.

If you do so, please create it as another github issue. With this comment, I'm closing the issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants