grafana / cuetsy

Experimental CUE->TypeScript exporter
Apache License 2.0
106 stars 8 forks source link

Allow deeper extends #107

Closed spinillos closed 1 year ago

spinillos commented 1 year ago

When we have complex cue schemas that extends from other cue files, sometimes the extends is missing. Our current loop tries to extract the value when it has a SelectorOP and sometimes, the dependency that we are looking for is deeper.

In a simple case, the structs that we have are like:

[.]  (struct)
├── (struct)
├── "OurExtend"
└── [ref:OurExtend]
    └── (struct) @cuetsy(kind="interface")

So dereferencing it, we can extract the value.

But for complex schemas, we can have something like:

[.]  (struct)
├── []  (struct)
│   └── [ref:composableKinds.DataQuery.lineage.schemas[0]]
│       └── [&]  (struct)
│           ├── (struct)
│           ├── [.]  (struct)
│           │   ├── (struct)
│           │   ├── "#SchemaDef"...
│           │   └── [ref:#SchemaDef]
│           │       └── (struct)
│           └── (struct)
├── "schema"
└── [ref:composableKinds.DataQuery.lineage.schemas[0].schema]
    └── [&]  (struct)
        ├── [&]  (struct)
        │   ├── [.]  (struct)
        │   │   ├── (struct)
        │   │   ├── "OurExtend"
        │   │   └── [ref:OurExtend]
        │   │       └── (struct) @cuetsy(kind="interface")
        │   └── (struct)
        └── _

And you can see that our desired extend is inside the dereference. In that case we need to iterate this deference until we find have a schema without the TopKind. This is important because its our stop condition. If we don't check this TopKind, we could continue iterating this schema and we could retrieve extends (if any) from our desired extend 😅. (For example, if OurExtend extends from Foo and Bar, we are going to retrieve these values instead of OurExtend)

sdboyer commented 1 year ago

Interesting! and awesome that you slayed this dragon 😄

i struggle with mentally turning the tree printer output back into the original source, but i think i'm seeing the issue here - the _ is likely coming from here.

On the one hand, this is solving something pretty specific to the way we've created thema's internal structures. On the other, it seems not-uncommon that in any moderately complex CUE constructs, _ is used as a placeholder for a field that's expected to be a coordination point for multiple unifications later. So, seems worth exploiting as a pattern, until we discover otherwise 😄