-
Notifications
You must be signed in to change notification settings - Fork 90
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
SALTO-7151: Fix "important values" generation for Swagger types #7104
base: main
Are you sure you want to change the base?
Conversation
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.
Looks good, added mainly questions :)
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 you please add a test covering a case when there are predefinedTypes
with important values?
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.
Done
log.timeDebug(() => { | ||
Object.entries(definedTypes).forEach(([typeName, type]) => { | ||
if (finalTypeNames?.has(typeName)) { | ||
log.trace('type %s is marked as final, not adjusting', type.elemID.getFullName()) |
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'm not sure about this... I think in this case we should add important values anyway
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.
Removed.
|
||
const { element: elementDef } = defQuery.query(typeName) ?? {} | ||
|
||
const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter( |
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 don't understand something 🤔 If importantValues can only exist on top level types, how can we set them for fields like Group's source.id ?
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 know this definitions were there before) commenting again after I saw the okta config with the (profile.login
)
something here looks odd to me... WDYT?
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.
Only top-level types can define important values, but they can use inner values to do so. If we needed to add important values to the inner type instead, it would force all types that have a field with that inner type to consider it an important value, which is less flexible.
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.
Thanks!
const { element: elementDef } = defQuery.query(typeName) ?? {} | ||
|
||
const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter( | ||
({ value }: ImportantValue) => type.fields[value] !== undefined, |
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.
just making sure .fields[value]
works with dot separated path?
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.
Replaced with getTypeInPath
which I've refactored to support primitive types. Thanks for the tip!
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override. | ||
if ( | ||
_.isEmpty(importantValues) && | ||
(type.annotations === undefined || type.annotations[CORE_ANNOTATIONS.IMPORTANT_VALUES] === undefined) |
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.
why is this part of the condition needed?
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.
Otherwise, we instantiate type.annotations
or type.annotations['_important_values']
as empty objects, which creates a diff in type nacls.
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.
shouldn't this be _.isEmpty(importantValues) ||
then? I'm probably missing something here, let's talk IRL 😄
Also the comment
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
what does "don't need an override" means?
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.
These conditions and the comment were relevant before I deleted the important value assignments in generateType
- back then, some types arrived to this function with some important values that needed to be overridden based on the type's actual field.
Now that I deleted that, I've also simplified the condition and the comment. Thanks!
defQuery: ElementAndResourceDefFinder<Options> | ||
finalTypeNames?: Set<string> | ||
}): void => | ||
log.timeDebug(() => { |
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.
nit: probably should be trace
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.
Done
// Generated duck-typed types may contain default important values that are not relevant, | ||
// so we want to override them at this point where we know what fields are actually relevant. |
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.
Why we need to add important values attributes in the two places ?
isn't this can fully replace https://github.com/salto-io/salto/blob/main/packages/adapter-components/src/fetch/element/type_element.ts#L233 ?
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.
Removed
1baa8be
to
e646fe5
Compare
e646fe5
to
a986741
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.
Looks great, thanks for this
let's talk IRL on https://github.com/salto-io/salto/pull/7104/files#r1921496870 cause I feel like i'm missing something
approving to unblock as the rest looks 💯
also FYI @netama incase you'd like to take a look
@@ -341,6 +348,64 @@ export const hideAndOmitFields = <Options extends FetchApiDefinitionsOptions>({ | |||
}) | |||
}, 'hideAndOmitFields') | |||
|
|||
export const getTypeInPath = ( |
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.
Thanks for adjusting & exporting this ! 🔥
As this is now exported can you please 🙏
- add a docstring
- cover in UT
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.
Done™ and Done™
if (isPrimitiveType(fieldType)) { | ||
log.warn('field %s in type %s is a primitive type, cannot recurse further', fieldName, type.elemID.getFullName()) | ||
return undefined | ||
} |
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 case is not valid as restPath
is not empty right? maybe it will be useful in the log?
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.
Refined the log message.
|
||
const { element: elementDef } = defQuery.query(typeName) ?? {} | ||
|
||
const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter( |
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.
Thanks!
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override. | ||
if ( | ||
_.isEmpty(importantValues) && | ||
(type.annotations === undefined || type.annotations[CORE_ANNOTATIONS.IMPORTANT_VALUES] === undefined) |
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.
shouldn't this be _.isEmpty(importantValues) ||
then? I'm probably missing something here, let's talk IRL 😄
Also the comment
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
what does "don't need an override" means?
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.
👑
Replace me with a description of the changes in this PR
Additional context for reviewer
Release Notes:
User Notifications:
None