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
refactor: flag resolver should use stricter types #2571
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
src/lib/routes/admin-api/index.ts
Outdated
@@ -112,6 +112,7 @@ class AdminApi extends Controller { | |||
this.app.use( | |||
'/invite-link', | |||
conditionalMiddleware( | |||
// @ts-expect-error | |||
() => config.flagResolver.isEnabled('publicSignup'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the strays caught by the PR - Maybe it's a check we should clean up? Or, on the other hand, correctly add to the remaining feature flags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed. @Tymek We might have missed this one when cleaning up?
src/lib/types/experimental.ts
Outdated
@@ -64,15 +65,17 @@ export const defaultExperimentalOptions = { | |||
|
|||
export interface IExperimentalOptions { | |||
flags: { | |||
[key: string]: boolean; | |||
E?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It it supposed to be some generic or a typo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed in: https://unleash-internal.slack.com/archives/C046LV6HH6W/p1669880769980979 - Needed to include this option since it's being passed in:
unleash/src/lib/create-config.ts
Lines 101 to 112 in bc3744d
function loadUI(options: IUnleashOptions): IUIConfig { | |
const uiO = options.ui || {}; | |
const ui: IUIConfig = { | |
environment: 'Open Source', | |
}; | |
ui.flags = { | |
E: true, | |
ENABLE_DARK_MODE_SUPPORT: false, | |
}; | |
return mergeAll([ui, uiO]); | |
} |
src/lib/util/flag-resolver.test.ts
Outdated
@@ -14,9 +14,11 @@ test('should produce UI flags with extra dynamic flags', () => { | |||
...defaultExperimentalOptions, | |||
flags: { extraFlag: false }, | |||
}; | |||
// @ts-expect-error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we get rid of those?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. const resolver = new FlagResolver(config as IExperimentalOptions);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
casting seems to be more idiomatic in TS tests than expecting errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, addressed in e226e30.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
questions inline
d5af045
to
e226e30
Compare
Before we merge this, will this break enterprise and cloud builds since they don't explicitly type? We should at least be aware that this can happen and update these in quick succession. |
Thinking a bit more about this, the IFlagKey type might be too limiting. If we only allow the flags defined in unleash, then the external flag provider has to implement an interface that only allows these flags. This can be problematic when we have flags that we want to define outside of unleash. For example, what if we wanted to have a feature flag specifically for unleash-cloud or unleash-enterprise? One specific example that comes to mind is change requests, which is a flag that is not in experimental options in unleash, because it's only used in enterprise. I think we need to consider a less restrictive type, but one that still allows the autocompletion. There should be a possibility to a looser type using the index access type of an object. |
Hey @FredrikOseberg,
A quick test locally seemed to work as intended, but it would be great if you could have a look as well just to double check.
Seems like unleash/src/lib/types/experimental.ts Line 74 in 4a3d260
This seems like the right approach to me. A looser type would also mean we would lose some things, like easily catching a stray like this: #2571 (comment) You would still have these options:
This flow seems better to me and more explicit than what we had before, WDYT? |
78cb843
to
b82c679
Compare
b82c679
to
fbdce30
Compare
0992672
to
0186683
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for now. If we discover any limitations we could always go back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that this should allow us to see which features are enabled, and what our legal keys to use are, rather than like what we have now, where you could theoretically just ask for any key.
The disadvantage is of course that we have to remember to code it in here, rather than having to just add a feature toggle in the Unleash Hosted UI. I find that I like the trade-off.
But would really like someone else to chime in as well.
Also, this looks quite like Cognite's way of doing the Rust client, where you need your feature key in an enum to be able to query for its enabled status. When writing tools like Edge and the proxy, it's a hindrance, but when using in our own controlled App, having a type that catches typos and non-existing toggles is 👍 for me
Adding stricter types to
FlagResolver
can possibly help improve our DX - Help us prevent errors like typos, guide us to correctly add a flag when needed, and warn us of stray checks whenever we do a clean up at a later stage.