typespec icon indicating copy to clipboard operation
typespec copied to clipboard

Bug when using `@withVisibilityFilter` decorator and reusing models

Open lopezm94 opened this issue 8 months ago • 2 comments

I'm working on a use case where I need to use the decorator @withVisibilityFilter to filter models over different set of combinations of a custom visibility enum. However, I'm encountering issues with the decorator in general, whether it is using my own custom visibility enum or using the Lifecycle one. I have managed to reproduce one case where I have problems in a minimal example on the playground using the standard visibility.

model Version {
  version: string;
}
model Property {
  @visibility(Lifecycle.Create)
  id: string;
  @visibility(Lifecycle.Read)
  version?: Version;
}
@withVisibilityFilter(#{any: #[Lifecycle.Read]})
model ReadProperty {
  ...Property
}

Link to bug in playground

This is issue can be made to work in two ways. One is by embedding the definition of the Version model into property.

model Property {
  @visibility(Lifecycle.Create)
  id: string;
  @visibility(Lifecycle.Read)
  version?: {
    version: string;
  };
}
@withVisibilityFilter(#{any: #[Lifecycle.Read]})
model ReadProperty {
  ...Property
}

Link to "fix" in playground

The second way to fix it is to use the decorator @withVisibility instead.

model Version {
  version: string;
}
model Property {
  @visibility(Lifecycle.Create)
  id: string;
  @visibility(Lifecycle.Read)
  version?: Version;
}
@withVisibility(Lifecycle.Read)
model ReadProperty {
  ...Property
}

Link to "fix" in playground

Non of these "fixes" are attractive to my use case. I prefer not to use the 1st "fix" because I'll end up with big nested models that cannot be reused. And the second "fix" is for filtering use cases that are very simple, to give you an idea I created a custom visibility where I generate models using a visibility filter like this:

// Properties that can be set during creation but cannot be changed
@withVisibilityFilter(#{ none: #[State.Generated] , any: #[State.Key, State.Immutable]})
model SettableOnlyDuringCreation<MODEL> {
  ...MODEL,
}

Is there an alternative way of representing this filter in a way that won't give me problems?

lopezm94 avatar May 13 '25 16:05 lopezm94

I think this has been fixed in main already and should be available in the next release of typespec(2-3 weeks), You can use the next(-dev) versions to try it out now. See the next playground

timotheeguerin avatar May 13 '25 17:05 timotheeguerin

Thanks @timotheeguerin! It does work for this small case scenario, however it is still happening on my real case scenario. I'll try to reproduce the issue in a smaller format.

lopezm94 avatar May 13 '25 22:05 lopezm94

Hi @@lopezm94. Since there hasn't been recent engagement, we're going to close this out. Please feel free to reopen if you have any further questions or concerns.