Skip to content

Conversation

@kkartunov
Copy link
Contributor

export interface AuthConfig {
user: AuthUser
profileCompletionData: ProfileCompletionData
user?: AuthUser

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
Making user optional in the AuthConfig interface could lead to runtime errors if the rest of the codebase assumes user is always defined. Ensure that all usages of AuthConfig handle the case where user is undefined.

user: AuthUser
profileCompletionData: ProfileCompletionData
user?: AuthUser
profileCompletionData?: ProfileCompletionData

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
Making profileCompletionData optional in the AuthConfig interface could lead to runtime errors if the rest of the codebase assumes profileCompletionData is always defined. Ensure that all usages of AuthConfig handle the case where profileCompletionData is undefined.

role="button"
tabindex="0"
on:click={() => toggleItem(item)}
on:keydown={(ev) => ev.key === 'Enter' && toggleItem(item)}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ accessibility]
The on:keydown event handler should also handle the 'Space' key to improve accessibility, as it is a common key for activating buttons. Consider updating the condition to (ev) => (ev.key === 'Enter' || ev.key === ' ') && toggleItem(item).

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better modularity and to avoid global namespace pollution. However, using as * can still lead to namespace conflicts. Consider using a specific namespace instead of * to prevent potential issues in larger projects.

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better modularity and avoiding global namespace pollution. However, using as * imports all variables into the global scope, which can lead to similar issues as @import. Consider importing only the necessary variables or using a namespace to avoid potential conflicts.

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * negates some of these benefits by making all variables and mixins globally available. Consider using a namespace instead to maintain encapsulation and improve maintainability.

function itemHasHoverMenu(menuItem: NavMenuItem) {
return menuItem.children?.length || menuItem.description;
return !!(menuItem.children?.length) || !!menuItem.description;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
The use of double negation !! is unnecessary here and can reduce readability. Consider using Boolean() for clarity.

}
hoveredElement = ev.target;
hoveredElement = ev.currentTarget as HTMLElement ?? undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
Using ev.currentTarget as HTMLElement ?? undefined is redundant. ev.currentTarget should always be an HTMLElement in this context. Consider simplifying to ev.currentTarget as HTMLElement.

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for modularity and avoiding global namespace pollution. However, using as * reintroduces the risk of namespace conflicts. Consider using a specific namespace instead of * to maintain modularity benefits.

<div class={styles.mobileMenuWrap} transition:fade={{duration: 200}}>
<TopNavbar style="primary" showLogo={false}>
<div class={styles.closeIcon} slot="right" on:click={handleClose} on:keydown={() => {}}>
<div class={styles.closeIcon} role="button" tabindex="0" slot="right" on:click={handleClose} on:keydown={() => {}}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ accessibility]
The on:keydown handler is currently an empty function. This could lead to unexpected behavior if users attempt to interact with the button using the keyboard. Consider implementing keyboard accessibility by handling key events such as Enter or Space to trigger handleClose.

* @param el
*/
function unBindEvents(el: HTMLElement = targetEl) {
function unBindEvents(el: HTMLElement | undefined = targetEl) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The change to allow el to be undefined in the unBindEvents function signature is appropriate given the default value of targetEl. However, ensure that all calls to unBindEvents handle the possibility of undefined correctly, especially if the function is used elsewhere in the codebase.

}
el.dataset.targetKey = undefined
delete el.dataset.targetKey

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Using delete el.dataset.targetKey instead of setting it to undefined is a better approach as it removes the attribute entirely, which is more semantically correct and avoids leaving an empty attribute. Ensure this change is consistent with any logic that checks for the presence of data-target-key.

@import 'lib/styles/mixins.scss';
@import 'lib/styles/fonts.scss';
@import 'lib/styles/colors.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * defeats this purpose by exposing all members to the global scope. Consider using specific namespaces instead of as * to maintain encapsulation.

@import 'lib/styles/fonts.scss';
@import 'lib/styles/colors.scss';
@use 'lib/styles/mixins.scss' as *;
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Using @use 'lib/styles/fonts.scss' as *; exposes all members globally, which can lead to conflicts and maintenance challenges. It's recommended to use a specific namespace to keep the scope limited and avoid potential issues.

@import 'lib/styles/colors.scss';
@use 'lib/styles/mixins.scss' as *;
@use 'lib/styles/fonts.scss' as *;
@use 'lib/styles/colors.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The @use 'lib/styles/colors.scss' as *; statement exposes all members globally, which can lead to conflicts and maintenance challenges. Consider using a specific namespace to keep the scope limited and avoid potential issues.

function handleNavigation(ev: MouseEvent, menuItem: NavMenuItem) {
if (typeof navigationHandler === 'function') {
if (typeof navigationHandler === 'function' && menuItem.url) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The added check menuItem.url ensures that menuItem.url is defined before attempting to use it in navigationHandler. This is a good improvement for preventing potential runtime errors. However, consider adding a more explicit error handling or logging mechanism if menuItem.url is undefined, to aid in debugging and provide better feedback.

@@ -1,4 +1,4 @@
@import 'lib/styles/mixins.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better modularity and to avoid potential conflicts. However, using as * can negate some of the benefits of @use by exposing all variables and mixins globally. Consider importing only the specific mixins or variables needed to maintain encapsulation and prevent unintended side effects.

@@ -1,4 +1,4 @@
@import 'lib/styles/mixins.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better modularity and to avoid namespace conflicts. However, using as * can negate some of these benefits by polluting the global namespace. Consider importing only the necessary mixins explicitly to maintain modularity and avoid potential conflicts.

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * negates some of these benefits by exposing all variables and mixins globally. Consider using a specific namespace instead of * to maintain encapsulation and avoid potential conflicts.

@@ -1,5 +1,5 @@
@import 'lib/styles/fonts.scss';
@import 'lib/styles/mixins.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * effectively negates this benefit by importing all members into the global scope. Consider importing only the specific members needed to maintain encapsulation.

@import 'lib/styles/fonts.scss';
@import 'lib/styles/mixins.scss';
@use 'lib/styles/fonts.scss' as *;
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Similar to the previous line, using @use 'lib/styles/mixins.scss' as * imports all members into the global scope, which can lead to namespace conflicts and reduced maintainability. It's better to import only the necessary members.

<div class={classnames(styles.modalWrap, $$props.class, size && `size-${size}`)}>
<div class={styles.modalContainer}>
<div class={styles.modalOverlay} transition:fade={{duration: 200}} on:click={() => isVisible = false} on:keydown={() => {}} />
<div class={styles.modalOverlay} role="button" tabindex="0" transition:fade={{duration: 200}} on:click={() => isVisible = false} on:keydown={() => {}} />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The on:keydown handler is currently an empty function. If this is intentional, consider removing it to avoid confusion, or implement the desired functionality.

class={styles.closeBtn}
on:click={() => isVisible = ''}
on:click={() => isVisible = false}
on:keydown={() => {}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The on:keydown handler is an empty function. If no functionality is intended, consider removing it to improve code clarity.

let elYOffset = 0;
function handleScroll() {
if (!elRef) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The check for elRef being undefined is a good addition to prevent errors, but consider initializing elRef to null instead of undefined for better clarity and consistency with DOM element references.

}
onMount(() => {
if (!elRef) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The check for elRef being undefined is a good addition to prevent errors, but consider initializing elRef to null instead of undefined for better clarity and consistency with DOM element references.

@import 'lib/styles/mixins.scss';
@import 'lib/styles/fonts.scss';
@import 'lib/styles/colors.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * negates some of the benefits of @use by exposing all variables and mixins globally. Consider using specific namespaces or importing only what is necessary to maintain encapsulation.

import styles from './ToolMenu.module.scss';
let navMenuItems = getToolSelectorItems();
let navMenuItems: NavMenuItem[] = getToolSelectorItems() ?? [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of the nullish coalescing operator (??) to default getToolSelectorItems() to an empty array is a good practice for ensuring navMenuItems is always iterable. However, ensure that getToolSelectorItems() is expected to return null or undefined in some cases, as this could mask potential issues where the function fails to return the expected data.

<InlineSvg src="/assets/tools/sprite.svg" />
{#each navMenuItems as section, sectionIndex}
<div class={classnames(styles.toolSection, styles[section.label?.toLowerCase()])}>
{#if section}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The added if check for section ensures that the block is only rendered when section is truthy. This is a good safeguard, but verify that navMenuItems is expected to contain falsy values, as this could indicate an issue with data integrity.


<div class={styles.toolGroups}>
{#each section.children as group}
{#each section.children ?? [] as group}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Using the nullish coalescing operator (??) to default section.children to an empty array is a good practice for ensuring the each block is always iterable. However, confirm that section.children is expected to be null or undefined, as this could hide potential data issues.


<div class={styles.toolNavItems}>
{#each group.children as navItem}
{#each group.children ?? [] as navItem}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of the nullish coalescing operator (??) to default group.children to an empty array ensures that the each block is always iterable. Ensure that group.children is expected to be null or undefined, as this could mask potential data issues.

tabindex="0"
bind:this={elRef}
on:click={() => popupIsVisible = true}
on:keydown={() => {}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ accessibility]
The on:keydown handler is currently a no-op. If the intention is to make the element accessible via keyboard, consider implementing meaningful keyboard interactions, such as toggling popupIsVisible on Enter or Space key presses.

$ctx.auth = {...$ctx.auth, ready: false};
const authUser = await fetchUserProfile();
$ctx.auth = {...$ctx.auth, ready: true, user: authUser};
$ctx.auth = {...$ctx.auth, ready: true, user: authUser ?? undefined};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
Using the nullish coalescing operator (??) to default authUser to undefined is unnecessary here, as authUser will already be undefined if fetchUserProfile() returns null or undefined. Consider removing ?? undefined for clarity.

let initials: string = '';
$: initials = user['initials'] ?? (
$: initials = (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of as any to access user.initials can lead to potential runtime errors if the user object does not have the expected structure. Consider refining the type definition of AuthUser to include initials if it's a common property, or use a type guard to safely access it.

tabindex="0"
bind:this={elRef}
on:click={() => popupIsVisible = true}
on:keydown={() => {}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The on:keydown handler is currently a no-op. If this is intended for accessibility, consider implementing keyboard navigation support or removing it if not needed.

@import 'lib/styles/mixins.scss';
@import 'lib/styles/fonts.scss';
@import 'lib/styles/colors.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * defeats this purpose by exposing all members globally. Consider using specific namespaces or importing only the necessary members to maintain encapsulation.

@@ -1,5 +1,5 @@
@import 'lib/styles/mixins.scss';
@import 'lib/styles/fonts.scss';
@use 'lib/styles/mixins.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better encapsulation and avoiding global namespace pollution. However, using as * negates some of these benefits by still exposing all variables and mixins globally. Consider using specific namespaces instead of as * to maintain encapsulation and avoid potential conflicts.

@import 'lib/styles/mixins.scss';
@import 'lib/styles/fonts.scss';
@use 'lib/styles/mixins.scss' as *;
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Similar to the previous line, using @use 'lib/styles/fonts.scss' as *; exposes all variables and mixins globally, which can lead to conflicts and makes the code harder to maintain. It's recommended to use a specific namespace instead of as * to take full advantage of the @use directive's encapsulation.

* @returns Value of property or undefined
*/
export function getAuthJwtDomainProp<T = string|undefined>(prop: string): T {
const propRegex = new RegExp(`^https?:\/\/.*\/${prop}$`, 'i');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ security]
The regular expression ^https?:\/\/.*\/${prop}$ could potentially match unintended URLs if prop contains special regex characters. Consider escaping prop to ensure it is treated as a literal string.

* @returns {Authorization: 'Bearer'} or {}
*/
export function getRequestAuthHeaders() {
export function getRequestAuthHeaders(): Partial<{ Authorization : string }> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
The return type Partial<{ Authorization : string }> is technically correct, but it might be clearer to use Record<string, string> or { Authorization?: string } to explicitly indicate that the Authorization key is optional.

*/
export const filterRoutesByUserRole = (routes: NavMenuItem) => {
const userRoles = getUserAppRoles();
const userRoles = getUserAppRoles() ?? [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Using the nullish coalescing operator (??) to default userRoles to an empty array is a good approach to handle null or undefined values. However, ensure that getUserAppRoles() does not return other falsy values like false or 0 that might need different handling.


const filtered = filterRoutesByUserRole(menu);
return filtered?.children
return filtered?.children ?? [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Using the nullish coalescing operator (??) to default to an empty array is a good approach for handling potential undefined values. However, ensure that filtered.children is always expected to be an array or undefined. If filtered.children could be null, this change will still work correctly, but it's important to confirm the expected types.


// store fetched data in a local cache (de-duplicate immediate api calls)
const localCache = {};
const localCache: any = {};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Using any for localCache can lead to potential type safety issues. Consider defining a more specific type for localCache to ensure better type checking and maintainability.


// get the user roles that match the config/auth's user roles definitions
export const getUserAppRoles = (): AuthUser['roles'] | undefined => {
export const getUserAppRoles = (): AuthUser['roles'] => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The return type of getUserAppRoles was changed to AuthUser['roles'], which is non-nullable. Ensure that the function logic aligns with this change and that it always returns a valid roles array, even if empty.

* @returns Promise<AuthUser>
*/
export const fetchUserProfile = async (): Promise<AuthUser> => {
export const fetchUserProfile = async (): Promise<AuthUser | undefined> => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The return type of fetchUserProfile was changed to Promise<AuthUser | undefined>, but the JSDoc comment still states Promise<AuthUser>. Update the JSDoc to reflect the correct return type.



let resolve: (value: AuthUser) => void;
let resolve: (value: AuthUser) => void = () => {};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
The initialization of resolve with an empty function () => {} is potentially misleading. Consider using null or a more descriptive placeholder to indicate that it will be assigned later.

</script>

<div class={styles.menuBtn} on:click={() => menuIsVisible = true} on:keydown={() => {}}>
<div class={styles.menuBtn} role="button" tabindex="0" on:click={() => menuIsVisible = true} on:keydown={() => {}}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The on:keydown handler is currently an empty function. If this is intentional, consider removing it to avoid confusion. If it's meant to handle keyboard interactions, ensure it has the appropriate logic to improve accessibility.


@function color($base, $shade: default) {
$color: map-get(map-get($colors, $base), $shade);
$color: map.get(map.get($colors, $base), $shade);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The change from map-get to map.get is correct for using the @use syntax, but ensure that the sass:map module is supported in all environments where this code will run, as it requires Dart Sass. If compatibility with other Sass implementations is needed, consider maintaining backward compatibility.

@@ -1,4 +1,4 @@
@import 'lib/styles/fonts.scss';
@use 'lib/styles/fonts.scss' as *;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
Switching from @import to @use is a good practice for better modularity and to avoid global namespace pollution. However, using as * imports all the variables and mixins into the global scope, which can still lead to namespace conflicts. Consider importing only the necessary parts explicitly to improve maintainability.

role="button"
tabindex="0"
on:click={toggleMainMenu}
on:keydown={() => {}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ accessibility]
The on:keydown handler is currently an empty function. Consider implementing functionality to handle keyboard interactions, such as triggering toggleMainMenu on Enter or Space key presses, to improve accessibility for keyboard users.

const tokens: string[] = [];

for (const arg of args) {
if (typeof arg !== 'string' || !arg.trim()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
The check typeof arg !== 'string' || !arg.trim() can be simplified to !arg || typeof arg !== 'string' || !arg.trim(). This ensures that null and undefined are filtered out immediately, improving clarity.

];

let previousLoadPromise;
let previousLoadPromise: Promise<void> | undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The type annotation Promise<void> | undefined for previousLoadPromise is a good addition for clarity. However, ensure that all usages of previousLoadPromise handle the undefined case appropriately to avoid potential runtime errors.

const firstLink = document.getElementsByTagName('link')[0];
firstLink.parentNode.insertBefore(link, firstLink);
const parent = firstLink?.parentNode ?? document.head;
parent.insertBefore(link, firstLink ?? null);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 readability]
The use of firstLink ?? null as the second argument in insertBefore is technically correct, but using null as a fallback might not be necessary since insertBefore can handle null by appending the node to the end of the parent. Consider simplifying to parent.insertBefore(link, firstLink);.

* @returns NavMenuItem.children
*/
export const toMarketingHostUrls = ({ children = [] }: NavMenuItem, depth?: number) => {
export const toMarketingHostUrls = ({ children = [] }: NavMenuItem, depth: number = 0) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The change from an optional depth parameter to a default value of 0 is a good improvement for clarity and avoids potential undefined issues. However, ensure that all calls to toMarketingHostUrls are updated accordingly if they relied on depth being optional.

// safe escape if things get out of control
if (depth >= 9) {
return
return children

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Returning children instead of undefined when depth >= 9 is a safer approach, ensuring that the function consistently returns an array. However, verify that this change does not affect any logic that might have relied on the previous behavior.

@kkartunov kkartunov merged commit 23b4bfc into master Dec 10, 2025
12 checks passed
export const filterRoutes = (
navMenuItem: NavMenuItem,
filter: (n: NavMenuItem) => boolean,
depth: number = 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
The default value for depth is set to 0, which is fine, but consider documenting or ensuring that the caller is aware of this default behavior, especially if the function is used in contexts where depth control is critical.

navMenuItem: NavMenuItem,
filter: (n: NavMenuItem) => boolean,
depth: number = 0
): NavMenuItem | undefined => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The return type of filterRoutes is now NavMenuItem | undefined. Ensure that all consumers of this function handle the undefined case appropriately to avoid potential runtime errors.

* @returns NavMenuItem.children
*/
export const activateAuthenticatedRoutes = (isAuthenticated: boolean, { children = [] }: NavMenuItem, depth?: number) => {
export const activateAuthenticatedRoutes = (isAuthenticated: boolean, { children = [] }: NavMenuItem, depth: number = 0): NavMenuItem[] => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The return type of activateAuthenticatedRoutes is now explicitly NavMenuItem[]. Verify that this change aligns with the expected usage of this function throughout the codebase, as it may affect how the function's output is processed.

}
})(0, navMenu)
return undefined;
})(0, navMenu) ?? [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of ?? [] ensures that matchRoutes always returns an array, which is a good practice. However, ensure that this behavior is consistent with the expectations of any code that relies on matchRoutes returning undefined in some cases.

const activeRouteTrail = matchRoutes({ children: navMenuItems } as NavMenuItem, locationHref).filter(Boolean)

return typeof trailLevel === 'number' ? activeRouteTrail?.slice(trailLevel, 1) : activeRouteTrail
return typeof trailLevel === 'number' ? activeRouteTrail.slice(trailLevel, trailLevel + 1) : activeRouteTrail

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The slice operation in getActiveRoute now uses trailLevel + 1 as the end index, which is correct for extracting a single element. Ensure that this logic is consistent with the intended behavior of the function, especially if trailLevel can be out of bounds.


const appContext = ctx.get('appContext');
if (!appContext) {
throw new Error(`Navigation #${targetId} is missing context!`);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The check for appContext being falsy and throwing an error is good for ensuring that the context is present. However, consider adding more context to the error message to help with debugging, such as including the targetId or additional state information.

if (method === 'init') {
init.call(null, ...args)
const [targetId, cfg] = args as [string, NavigationAppProps?];
init(targetId, cfg ?? {} as NavigationAppProps)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of as [string, NavigationAppProps?] for type assertion is potentially unsafe if the args array does not match the expected structure. Consider adding runtime checks to ensure args has the expected length and types before destructuring.

else if (method === 'destroy') {
destroy.call(null, ...args);
const [targetId] = args as [string];
destroy(targetId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The type assertion as [string] assumes that args will always have a string as the first element. Consider adding a runtime check to validate this assumption to prevent potential runtime errors.

else if (method === 'trigger') {
appPubSub.publish.call(appPubSub, ...args);
const [name, data] = args as [string, unknown];
appPubSub.publish(name, data);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The type assertion as [string, unknown] assumes that args will always have a string and an unknown type. Consider adding runtime checks to validate these assumptions to prevent potential runtime errors.

const tcUnivNavConfig = (window[globalName] ?? {}) as any;
const queue = tcUnivNavConfig.q ?? [];
const globalName = (('TcUnivNavConfig' in window && (window as any).TcUnivNavConfig) || 'tcUniNav') as string;
const tcUnivNavConfig = ((globalName in window && (window as any)[globalName]) ?? {}) as { q?: unknown[] };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The use of as { q?: unknown[] } assumes that tcUnivNavConfig will have a property q that is an array. Consider adding a check to ensure q is an array before proceeding to avoid potential runtime errors.

export interface AuthConfig {
user: AuthUser;
profileCompletionData: ProfileCompletionData;
user?: AuthUser;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
Making user optional in the AuthConfig interface might lead to runtime errors if the rest of the codebase assumes user is always present. Ensure that all usages of AuthConfig handle the case where user is undefined.

user: AuthUser;
profileCompletionData: ProfileCompletionData;
user?: AuthUser;
profileCompletionData?: ProfileCompletionData;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
Making profileCompletionData optional in the AuthConfig interface might lead to runtime errors if the rest of the codebase assumes profileCompletionData is always present. Ensure that all usages of AuthConfig handle the case where profileCompletionData is undefined.

* @return {NavMenuItem} The filtered menu items based on the user roles
*/
export declare const filterRoutesByUserRole: (routes: NavMenuItem) => any;
export declare const filterRoutesByUserRole: (routes: NavMenuItem) => NavMenuItem | undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The return type has been changed from any to NavMenuItem | undefined, which improves type safety. Ensure that all usages of filterRoutesByUserRole handle the possibility of an undefined return value to prevent runtime errors.

export type fetchUserProfileFn = () => AuthUser | null;
export declare const getJwtUserhandle: () => AuthUser["handle"] | undefined;
export declare const getJwtUserRoles: () => AuthUser["roles"] | undefined;
export declare const getUserAppRoles: () => AuthUser["roles"];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The return type of getUserAppRoles was changed from AuthUser['roles'] | undefined to AuthUser['roles']. If undefined is a possible value in some cases, this change might lead to runtime errors. Ensure that undefined is not a valid return value, or handle it appropriately.

* @returns Promise<AuthUser>
*/
export declare const fetchUserProfile: () => Promise<AuthUser>;
export declare const fetchUserProfile: () => Promise<AuthUser | undefined>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The return type of fetchUserProfile was changed to Promise<AuthUser | undefined>. Ensure that all consumers of this function handle the potential undefined value to prevent runtime errors.

@@ -1 +1,2 @@
export declare const classnames: (...args: string[]) => string;
export type ClassValue = string | false | null | undefined;
export declare const classnames: (...args: ClassValue[]) => string;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The change to use ClassValue[] instead of string[] in the classnames function signature improves type safety by allowing more flexible input types. However, ensure that the implementation of the classnames function correctly handles these new types (false, null, undefined) to avoid unexpected behavior or runtime errors.

@@ -1,3 +1,3 @@
export declare const getCookieValue: (name: string) => any;
export declare const checkCookie: (cookieName: string, value?: any) => boolean;
export declare const checkCookie: (cookieName: string, value?: any) => true | undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The return type of checkCookie has been changed from boolean to true | undefined. This change implies that the function will never return false, which might be misleading if the function is expected to indicate the absence of a cookie or a mismatch in value. Consider whether this change accurately reflects the intended behavior and if it might lead to confusion or incorrect assumptions in the codebase.

@@ -1 +1 @@
export declare const checkAndLoadFonts: () => Promise<any>;
export declare const checkAndLoadFonts: () => Promise<void>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Changing the return type from Promise<any> to Promise<void> improves type safety by explicitly indicating that the function does not return a value. Ensure that all usages of checkAndLoadFonts are updated accordingly to handle this change.

* @returns NavMenuItem
*/
export declare const filterRoutes: (navMenuItem: NavMenuItem, filter: (n: NavMenuItem) => boolean, depth?: number) => any;
export declare const filterRoutes: (navMenuItem: NavMenuItem, filter: (n: NavMenuItem) => boolean, depth?: number) => NavMenuItem | undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The return type of filterRoutes has been changed from any to NavMenuItem | undefined. This is a positive change for type safety, but ensure that all usages of filterRoutes handle the possibility of undefined being returned to prevent potential runtime errors.

css: {
preprocessorOptions: {
scss: {
silenceDeprecations: ["legacy-js-api"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The silenceDeprecations option is used to suppress warnings for deprecated features. Ensure that this is a temporary measure and that there is a plan to address the deprecation warnings, as relying on deprecated features can lead to future maintenance issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants