Comments (6)
Hi @deiteris
We are already working on a refactor in the transformation code that resolves inheritance because we also detected some cases of inheritance mixed with recursion that have this same problem.
We still don't have an ETA for this, but it probably will be in the late May release.
from amf.
Hi @deiteris! This refactor was released in version 5.3.0. The latest version has some fixes on that inheritance resolution also. Do you want to test it to see if this still applies?
from amf.
Hi @tomsfernandez! The code I mentioned in the issue produces identical result in 5.3.0-0 and 5.4.0-1.
I've tried different transformation pipelines as well which also produce the same result (even though a more readable one). For example, this is the result of the Default pipeline:
http://a.ml/amf/default_document#/declares/union/Value
http://a.ml/amf/default_document#/declares/shape/TypeOne
http://a.ml/amf/default_document#/declares/union/Value/inherits/union/default-union/anyOf/union/default-union
http://a.ml/amf/default_document#/declares/shape/TypeTwo
http://a.ml/amf/default_document#/declares/union/Value/inherits/union/default-union/anyOf/union/default-union/anyOf/union/default-union
http://a.ml/amf/default_document#/declares/scalar/TypeThree
http://a.ml/amf/default_document#/declares/shape/TypeMap
What I also find concerning, is that this nesting seems to happen with any custom type even without recursive type (I guess might need to rename the issue). So, scalar TypeOne | TypeTwo | TypeThree
(that are just string | number | integer
) will also produce this sequence with nesting:
http://a.ml/amf/default_document#/declares/union/Value
http://a.ml/amf/default_document#/declares/scalar/TypeOne
http://a.ml/amf/default_document#/declares/union/Value/inherits/union/default-union/anyOf/union/default-union
http://a.ml/amf/default_document#/declares/scalar/TypeTwo
http://a.ml/amf/default_document#/declares/scalar/TypeThree
While union of plain string | number | integer
produces correct sequence:
http://a.ml/amf/default_document#/declares/union/PlainUnion
http://a.ml/amf/default_document#/declares/union/PlainUnion/inherits/union/default-union/anyOf/scalar/default-scalar
http://a.ml/amf/default_document#/declares/union/PlainUnion/inherits/union/default-union/anyOf/scalar/default-scalar_1
http://a.ml/amf/default_document#/declares/union/PlainUnion/inherits/union/default-union/anyOf/scalar/default-scalar_2
I've been making my own expression parser and it seems to me as if CST which was used to generate AST is as follows:
(Value: union
(null: union (TypeOne: custom_type) (TypeTwo: custom_type))
(TypeThree: custom_type)
)
Which may happen in case |
is treated as an operator and associated to left/right value.
While what I expect (and managed to achieve) is:
(Value: union (TypeOne: custom_type) (TypeTwo: custom_type) (TypeThree: custom_type)))
from amf.
As a workaround, I've flatten such union structure in my own code (v5.4.0-1) in the flattenUnion
function, just in case someone finds it useful:
import amf, { Module, Shape, TypeIRI, TypeUtil, UnionShape } from 'amf-client-js'
const raml = `
#%RAML 1.0 Library
types:
TypeOne:
properties:
prop3: string | integer
TypeTwo:
properties:
prop1: string
prop2?: string
TypeThree:
properties:
prop5: boolean
TypeMap:
properties:
prop4: Value
Value:
type: TypeOne | TypeTwo | TypeThree | TypeMap
`;
(async () => {
const client = amf.RAMLConfiguration.RAML10().baseUnitClient()
const data = await client.parseContent(raml)
//const result = client.transform(data.baseUnit, amf.PipelineId.Default)
function flattenUnion(shape: UnionShape, shapes: Shape[] = []): Shape[] {
for (const t of shape.anyOf) {
if (TypeUtil.isTypeOf(t, TypeIRI.UnionShape) && t.name.isNull) {
flattenUnion(t as UnionShape, shapes)
} else {
shapes.push(t)
}
}
return shapes
}
function traverse(type: Shape) {
console.log(type.isLink ? type.linkLabel.value() : type.name.value())
for (const parent of type.inherits) {
traverse(parent)
}
if (TypeUtil.isTypeOf(type, TypeIRI.UnionShape)) {
const shapes = flattenUnion(type as UnionShape)
for (const t of shapes) {
traverse(t)
}
}
}
traverse(((data.baseUnit as Module).declares as Shape[]).find(shape => shape.name.value() === 'Value')!)
})();
Outputs:
Value
null
TypeOne
TypeTwo
TypeThree
TypeMap
Without this workaround, the output is:
Value
null
TypeOne
null
TypeTwo
null
TypeThree
TypeMap
from amf.
Related Issues (20)
- Parser allows JSON schemas to participate in type specialization, expression and inheritance HOT 5
- RAML resource payload schemas cannot override resource-type payload schemas HOT 1
- Fetch detailed error message while validating the OAS file HOT 7
- npm package README is out of date HOT 1
- Type array is missing in the generated RAML specification HOT 15
- A RAML file referencing a security scheme in a library is converted into an invalid OAS3 file HOT 1
- JSON schema client doesn't resolve `$ref` links correctly HOT 1
- Derived object's property doesn't take precedence over parent's pattern property HOT 2
- Invalid scalar inheritance base type when specializing int64 type HOT 2
- Root-level annotations are lost and other are not validated correctly when loading already parsed AMF Graph HOT 2
- Validation stage tampers the parsed model HOT 2
- Validation throws an exception when loading parsed AMF Graph with examples in types HOT 2
- How to distinguish NilShape and AnyShape? HOT 2
- Cannot compute inheritance from union when specializing a union property with the `type` keyword HOT 2
- Windows version keeps using relative paths when parser accepts absolute path HOT 2
- Recursive shapes and manual traverse on raw model HOT 3
- Recursive object property HOT 2
- Using functionConstraint in validations HOT 3
- Using an Array in a custom extension HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from amf.