Skip to content

Commit 173f48c

Browse files
advances fixing linter
1 parent 86d0756 commit 173f48c

File tree

16 files changed

+130
-24
lines changed

16 files changed

+130
-24
lines changed

eslint.config.mjs

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,41 +81,141 @@ export default [
8181
},
8282
},
8383
rules: {
84-
// Nx boundaries
84+
/**
85+
* Nx boundaries
86+
* @see https://nx.dev/docs/features/enforce-module-boundaries
87+
* */
8588
'@nx/enforce-module-boundaries': [
8689
'error',
8790
{
8891
enforceBuildableLibDependency: true,
8992
allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?js$'],
90-
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }],
93+
depConstraints: [
94+
// example: apps can depend on ui + shared libs
95+
{
96+
sourceTag: 'type:app',
97+
onlyDependOnLibsWithTags: ['scope:ui', 'scope:shared', 'type:lib'],
98+
},
99+
// // define to which libraries ui can depend on
100+
// { sourceTag: 'scope:ui', onlyDependOnLibsWithTags: ['scope:ui', 'scope:shared'] },
101+
],
91102
},
92103
],
93104

94105
// General style
95106
'prettier/prettier': 'error',
96-
curly: ['error', 'all'],
97107

98108
// TypeScript
99109
// Removed duplicates already enforced by TypeScript:
100110
'no-unused-vars': 'off',
111+
112+
// ts checks these better than ESLint
101113
'no-redeclare': 'off',
102-
'no-dupe-class-members': 'off',
103-
'@typescript-eslint/no-shadow': 'off',
114+
115+
/**
116+
* This rule is redundant with `await` usage
117+
* async function foo() {
118+
* return await bar(); // `return bar()` is sufficient
119+
* }
120+
*
121+
* Also is covered by @no-floating-promises
122+
*/
104123
'@typescript-eslint/return-await': 'off',
105124

125+
/**
126+
* This rule is too restrictive in practice
127+
* const isAllow = useSomeHook(({ isAllow }) => isAllow); // will error
128+
*/
129+
'@typescript-eslint/no-shadow': 'off',
130+
131+
// allow to type primitive types explicitly like `let x: number = 5;` ✅
132+
'@typescript-eslint/no-inferrable-types': 'off',
133+
134+
/**
135+
* this rule is too restrictive in practice, e.g.,
136+
* expect(someAsyncFunction).toHaveBeenCalledWith(someArg); // will error because someAsyncFunction is async
137+
*/
138+
'@typescript-eslint/no-misused-promises': 'off',
139+
140+
// allow the exception pattern with leading for function with multiple args
106141
'@typescript-eslint/no-unused-vars': [
107142
'error',
108143
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
109144
],
145+
146+
// functions an classes always are hoisted so this rule does not make sense for them
110147
'@typescript-eslint/no-use-before-define': [
111148
'error',
112149
{ functions: false, classes: false, variables: true },
113150
],
151+
152+
// warn on develop so is not super annoying but will be rejected by husky pre-commit
114153
'@typescript-eslint/no-explicit-any': 'warn',
115154

155+
// eslint cannot accurately check unbound methods so best to disable it
156+
'@typescript-eslint/unbound-method': 'off',
157+
158+
/**
159+
* Empty functions are useful as placeholders or in tests
160+
*/
161+
'@typescript-eslint/no-empty-function': 'off',
162+
163+
// #region [TODO]: rules to review later
164+
/**
165+
* This rules are necessary in our code base but would require significant refactoring to enable them
166+
* By now we disable them since they were muted by configuration or explicit rules... but we want them enabled eventually
167+
*/
168+
169+
/**
170+
* Also necessary we should not render unknown values directly in templates
171+
*/
172+
'@typescript-eslint/restrict-template-expressions': 'off',
173+
174+
/**
175+
* Related with defensive programming
176+
* We need to remove this rule and assert the non-null values properly: TODO
177+
*/
178+
'@typescript-eslint/no-non-null-assertion': 'off',
179+
180+
/**
181+
* This one is also related with defensive programming
182+
* We need to assert every unknown value before using it: TODO
183+
*/
184+
'@typescript-eslint/no-unsafe-call': 'off',
185+
186+
/**
187+
* We need this rule to easier identify rejected promises origins
188+
* It will require refactoring to enable it though
189+
*/
190+
'@typescript-eslint/prefer-promise-reject-errors': 'off',
191+
192+
/**
193+
* Avoid unsafe assignments
194+
* We need to migrate to defensive programming and assert every unknown value before using it
195+
*/
196+
'@typescript-eslint/no-unsafe-assignment': 'off',
197+
'@typescript-eslint/no-unsafe-member-access': 'off',
198+
199+
/**
200+
* Super important to avoid deadened async errors or forgotten promises,
201+
* We already catch error because that could have been prevented by proper this rule usage
202+
* It will require significant refactoring to enable it though
203+
*/
204+
'@typescript-eslint/no-floating-promises': 'off',
205+
206+
/**
207+
* Avoid creating class and interface with same name
208+
* We need this but it requires refactoring to enable it
209+
*/
210+
'@typescript-eslint/no-unsafe-declaration-merging': 'off',
211+
'no-dupe-class-members': 'off',
212+
213+
// #endregion
214+
116215
// React
117216
'react/react-in-jsx-scope': 'off',
118217
'react/jsx-uses-react': 'off',
218+
119219
'react-hooks/rules-of-hooks': 'error',
120220
'react-hooks/exhaustive-deps': 'warn',
121221

frontend/src/hooks/useDevices.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const useDevices = () => {
3838
console.warn('enumerateDevices() not supported.');
3939
return;
4040
}
41-
// eslint-disable-next-line consistent-return
41+
4242
return new Promise<void>((_resolve, reject) => {
4343
// Vonage Video API's getDevices retrieves all audio and video input devices
4444
getDevices(async (err?: OTError, devices?: Device[]) => {

frontend/src/hooks/useLayoutManager.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type GetLayout = InstanceType<typeof LayoutManager>['getLayout'];
1111
*/
1212
const useLayoutManager = (): GetLayout => {
1313
const layoutManager = useRef(new LayoutManager());
14+
// eslint-disable-next-line react-hooks/refs
1415
return layoutManager.current.getLayout.bind(layoutManager.current);
1516
};
1617

frontend/src/hooks/useRoomName.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const useRoomName = ({ useLocationState = false }: UseRoomNameProps = {}): strin
2323
// this is the default behavior of this hook
2424
roomName = params.roomName;
2525
}
26-
const lowerCaseRoomName = roomName?.toLowerCase() || '';
26+
const lowerCaseRoomName: string = roomName?.toLowerCase() || '';
2727

2828
return lowerCaseRoomName;
2929
};

frontend/src/hooks/useScreenShare.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const useScreenShare = (): UseScreenShareType => {
4747
}
4848
}, [unpublish]);
4949

50-
const handleStreamCreated = useCallback(async () => {
50+
const handleStreamCreated = useCallback(() => {
5151
unpublishScreenshare();
5252
}, [unpublishScreenshare]);
5353

@@ -116,6 +116,10 @@ const useScreenShare = (): UseScreenShareType => {
116116
toggleShareScreen,
117117
isSharingScreen,
118118
screenshareVideoElement,
119+
/**
120+
* On the first render this will return null
121+
*/
122+
// eslint-disable-next-line react-hooks/refs
119123
screensharingPublisher: screenSharingPub.current,
120124
};
121125
};

frontend/src/hooks/useToolbarButtons.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ const useToolbarButtons = ({
107107

108108
observer.current.observe(toolbarRef.current);
109109

110-
// eslint-disable-next-line consistent-return
111110
return () => {
112111
if (observedToolbar) {
113112
observer.current?.unobserve(observedToolbar);

frontend/src/pages/MeetingRoom/MeetingRoom.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import usePublisherOptions from '@Context/PublisherProvider/usePublisherOptions'
2828
import { makeAppConfigProviderWrapper } from '@test/providers';
2929
import composeProviders from '@utils/composeProviders';
3030
import MeetingRoom from './MeetingRoom';
31+
import { Box } from 'opentok-layout-js';
3132

3233
const mockedNavigate = vi.fn();
3334
const mockedParams = { roomName: 'test-room-name' };
@@ -165,7 +166,7 @@ describe('MeetingRoom', () => {
165166
left: 0,
166167
top: 0,
167168
width: 1280,
168-
});
169+
}) as Box[];
169170
});
170171
mockUseSessionContext.mockReturnValue(sessionContext as unknown as SessionContextType);
171172
mockUseActiveSpeaker.mockReturnValue(undefined);

frontend/src/pages/MeetingRoom/MeetingRoom.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,8 @@ const MeetingRoom = (): ReactElement => {
110110
}
111111
}, [accessStatus]);
112112

113-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
114113
useRedirectOnPublisherError(publishingError);
115114

116-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
117115
useRedirectOnSubscriberError(subscriptionError);
118116

119117
return (

frontend/src/pages/WaitingRoom/WaitingRoom.spec.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ describe('WaitingRoom', () => {
149149

150150
const { rerender, container } = render(<WaitingRoomWithProviders />);
151151

152+
// TODO: investigate why this needs to be awaited or the test fails
153+
// eslint-disable-next-line @typescript-eslint/await-thenable
152154
await act(() => {
153155
rerender(<WaitingRoomWithProviders />);
154156
});
@@ -182,7 +184,7 @@ describe('WaitingRoom', () => {
182184
expect(mockedDestroyPublisher).toHaveBeenCalled();
183185
});
184186

185-
it('should reload window when device permissions change', async () => {
187+
it('should reload window when device permissions change', () => {
186188
const { rerender } = render(<WaitingRoomWithProviders />);
187189
expect(globalThis.location.reload).not.toBeCalled();
188190

@@ -201,7 +203,7 @@ describe('WaitingRoom', () => {
201203
*/
202204
function getLocationMock() {
203205
const { location } = globalThis;
204-
const locationMock = Object.create(Object.getPrototypeOf(location));
206+
const locationMock = Object.create(Object.getPrototypeOf(location) as Location);
205207

206208
Object.assign(locationMock, location);
207209

frontend/src/test/globals.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable import/prefer-default-export */
21
// src/test-globals.ts
32
export const setup = () => {
43
process.env.TZ = 'US/Eastern';

0 commit comments

Comments
 (0)