瀏覽代碼

chore: fix eslint warinings

Nicolas Meienberger 2 年之前
父節點
當前提交
6dbc831624

+ 2 - 1
.eslintrc.js

@@ -1,5 +1,5 @@
 module.exports = {
-  plugins: ['@typescript-eslint', 'import', 'react', 'jest', 'jsdoc'],
+  plugins: ['@typescript-eslint', 'import', 'react', 'jest', 'jsdoc', 'jsx-a11y'],
   extends: [
     'plugin:@typescript-eslint/recommended',
     'next/core-web-vitals',
@@ -11,6 +11,7 @@ module.exports = {
     'prettier',
     'plugin:react/recommended',
     'plugin:jsdoc/recommended',
+    'plugin:jsx-a11y/recommended',
   ],
   parser: '@typescript-eslint/parser',
   parserOptions: {

+ 3 - 3
src/client/components/Layout/Layout.tsx

@@ -19,7 +19,7 @@ interface IProps {
 
 export const Layout: React.FC<IProps> = ({ children, breadcrumbs, title, actions }) => {
   const router = useRouter();
-  const refreshToken = trpc.auth.refreshToken.useMutation({
+  const { mutate } = trpc.auth.refreshToken.useMutation({
     onSuccess: (data) => {
       if (data?.token) localStorage.setItem('token', data.token);
     },
@@ -30,8 +30,8 @@ export const Layout: React.FC<IProps> = ({ children, breadcrumbs, title, actions
   });
 
   useEffect(() => {
-    refreshToken.mutate();
-  }, []);
+    mutate();
+  }, [mutate]);
 
   const { version } = useSystemStore();
   const defaultVersion = '0.0.0';

+ 1 - 1
src/client/mocks/fixtures/app.fixtures.ts

@@ -5,7 +5,7 @@ import { App, AppCategory, AppInfo, AppWithInfo } from '../../core/types';
 const randomCategory = (): AppCategory[] => {
   const categories = Object.values(APP_CATEGORIES);
   const randomIndex = faker.datatype.number({ min: 0, max: categories.length - 1 });
-  return [categories[randomIndex]!];
+  return [categories[randomIndex] as AppCategory];
 };
 
 export const createApp = (overrides?: Partial<AppInfo>): AppInfo => {

+ 1 - 1
src/client/mocks/getTrpcMock.ts

@@ -25,7 +25,7 @@ export type RpcErrorResponse = {
   };
 };
 
-const jsonRpcSuccessResponse = (data: unknown): RpcSuccessResponse<any> => {
+const jsonRpcSuccessResponse = (data: unknown): RpcSuccessResponse<unknown> => {
   const response = SuperJSON.serialize(data);
 
   return {

+ 3 - 0
src/client/mocks/index.ts

@@ -1,3 +1,6 @@
+/**
+ * This file is the entry point for the mock service worker.
+ */
 async function initMocks() {
   if (typeof window === 'undefined') {
     const { server } = await import('./server');

+ 6 - 6
src/client/modules/AppStore/components/CategorySelector/CategorySelector.tsx

@@ -36,28 +36,28 @@ const CategorySelector: React.FC<IProps> = ({ onSelect, className, initialValue
       className={className}
       value={value}
       styles={{
-        menu: (provided: any) => ({
+        menu: (provided: object) => ({
           ...provided,
           backgroundColor: bgColor,
           color,
         }),
-        control: (provided: any) => ({
+        control: (provided: object) => ({
           ...provided,
           backgroundColor: bgColor,
           color,
           borderColor,
         }),
-        option: (provided: any, state: any) => ({
+        option: (provided: object, state: { isFocused: boolean }) => ({
           ...provided,
           backgroundColor: state.isFocused ? '#243049' : bgColor,
           color: state.isFocused ? '#fff' : color,
         }),
-        singleValue: (provided: any) => ({
+        singleValue: (provided: object) => ({
           ...provided,
           color,
           fontSize: '0.8rem',
         }),
-        placeholder: (provided: any) => ({
+        placeholder: (provided: object) => ({
           ...provided,
           color: '#a5a9b1',
           fontSize: '0.8rem',
@@ -66,7 +66,7 @@ const CategorySelector: React.FC<IProps> = ({ onSelect, className, initialValue
       onChange={handleChange}
       defaultValue={[]}
       name="categories"
-      options={options as any}
+      options={options}
       placeholder="Category"
     />
   );

+ 5 - 0
src/client/utils/trpc.ts

@@ -3,6 +3,11 @@ import { createTRPCNext } from '@trpc/next';
 import superjson from 'superjson';
 import type { AppRouter } from '../../server/routers/_app';
 
+/**
+ * Get base url for the current environment
+ *
+ * @returns {string} base url
+ */
 function getBaseUrl() {
   if (typeof window !== 'undefined') {
     // browser should use relative path

+ 6 - 0
src/client/utils/typescript.ts

@@ -1,5 +1,11 @@
 const objectKeys = <T extends object>(obj: T): (keyof T)[] => Object.keys(obj) as (keyof T)[];
 
+/**
+ * Type guard to check if a value is not null or undefined
+ *
+ * @param {any} value - The value to check
+ * @returns {value is NonNullable<any>} - True if the value is not null or undefined
+ */
 function nonNullable<T>(value: T): value is NonNullable<T> {
   return value !== null && value !== undefined;
 }

+ 6 - 0
src/pages/_app.tsx

@@ -11,6 +11,12 @@ import { StatusProvider } from '../client/components/hoc/StatusProvider';
 import { trpc } from '../client/utils/trpc';
 import { SystemStatus, useSystemStore } from '../client/state/systemStore';
 
+/**
+ * Next.js App component
+ *
+ * @param {AppProps} props - props passed to the app
+ * @returns {JSX.Element} - JSX element
+ */
 function MyApp({ Component, pageProps }: AppProps) {
   const { setDarkMode } = useUIStore();
   const { setStatus, setVersion, pollStatus } = useSystemStore();

+ 5 - 0
src/pages/_document.tsx

@@ -3,6 +3,11 @@ import { Html, Head, Main, NextScript } from 'next/document';
 
 import { getUrl } from '../client/core/helpers/url-helpers';
 
+/**
+ * Next.js Document component
+ *
+ * @returns {JSX.Element} - JSX element
+ */
 export default function MyDocument() {
   return (
     <Html lang="en">

+ 8 - 4
src/server/context.ts

@@ -11,19 +11,23 @@ type CreateContextOptions = {
   session: Session | null;
 };
 
-/** Use this helper for:
+/**
+ * Use this helper for:
  * - testing, so we dont have to mock Next.js' req/res
  * - trpc's `createSSGHelpers` where we don't have req/res
+ *
+ * @param {CreateContextOptions} opts - options
  * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
- * */
+ */
 export const createContextInner = async (opts: CreateContextOptions) => ({
   session: opts.session,
 });
 
 /**
  * This is the actual context you'll use in your router
- * @link https://trpc.io/docs/context
- * */
+ *
+ * @param {CreateNextContextOptions} opts - options
+ */
 export const createContext = async (opts: CreateNextContextOptions) => {
   const { req, res } = opts;
 

+ 0 - 3
src/server/core/EventDispatcher/EventDispatcher.test.ts

@@ -1,6 +1,3 @@
-/**
- * @jest-environment node
- */
 import fs from 'fs-extra';
 import { EventDispatcher } from '.';
 

+ 3 - 1
src/server/core/EventDispatcher/EventDispatcher.ts

@@ -94,6 +94,8 @@ class EventDispatcher {
 
   /**
    * Poll queue and run events
+   *
+   * @returns {NodeJS.Timer} - Interval timer
    */
   private pollQueue() {
     Logger.info(`EventDispatcher(${this.dispatcherId}): Polling queue...`);
@@ -207,7 +209,7 @@ class EventDispatcher {
    *
    * @param {EventType} type - Event type
    * @param {[string[]]} args - Event arguments
-   * @returns - Promise that resolves when the event is done
+   * @returns {Promise<{ success: boolean; stdout?: string }>} - Promise that resolves when the event is done
    */
   public async dispatchEventAsync(type: EventType, args?: string[]): Promise<{ success: boolean; stdout?: string }> {
     const event = this.dispatchEvent(type, args);

+ 0 - 2
src/server/core/TipiConfig/TipiConfig.ts

@@ -95,13 +95,11 @@ export class TipiConfig {
         this.config = parsedConfig.data;
       } else {
         const errors = formatErrors(parsedConfig.error.flatten());
-        console.error(`❌ Invalid env config\n${errors}`);
         Logger.error(`❌ Invalid env config\n\n${errors}`);
         throw new Error('Invalid env config');
       }
     } else {
       const errors = formatErrors(parsedFileConfig.error.flatten());
-      console.error(`❌ Invalid settings.json file:\n${errors}`);
       Logger.error(`❌ Invalid settings.json file:\n${errors}`);
       throw new Error('Invalid settings.json file');
     }

+ 1 - 1
src/server/index.ts

@@ -36,7 +36,7 @@ nextApp.prepare().then(async () => {
   app.use('/static', express.static(`${getConfig().rootFolder}/repos/${getConfig().appsRepoId}/`));
 
   app.all('*', (req, res) => {
-    const parsedUrl = parse(req.url!, true);
+    const parsedUrl = parse(req.url, true);
 
     handle(req, res, parsedUrl);
   });

+ 3 - 4
src/server/services/apps/apps.helpers.ts

@@ -212,9 +212,9 @@ export const generateEnvFile = (app: App) => {
   This function reads the apps directory and skips certain system files, then reads the config.json and metadata/description.md files for each app,
   parses the config file, filters out any apps that are not available and returns an array of app information.
   If the config.json file is invalid, it logs an error message.
-
+ 
   @returns {Promise<AppInfo[]>} - Returns a promise that resolves with an array of available apps' information.
-*/
+ */
 export const getAvailableApps = async () => {
   const appsDir = readdirSync(`/runtipi/repos/${getConfig().appsRepoId}/apps`);
 
@@ -248,7 +248,6 @@ export const getAvailableApps = async () => {
  *  If the app is not found, it returns null.
  *
  *  @param {string} id - The app id.
- *  @param {number} [version] - The current version of the app.
  *  @returns {Promise<{current: number, latest: number, dockerVersion: string} | null>} - Returns an object containing information about the updates available for the app or null if the app is not found or has an invalid config.json file.
  */
 export const getUpdateInfo = (id: string) => {
@@ -273,7 +272,7 @@ export const getUpdateInfo = (id: string) => {
  *  If an error occurs during the process, it logs the error message and throws an error.
  *
  *  @param {string} id - The app id.
- *  @param {AppStatus} [status] - The app status.
+ *  @param {App['status']} [status] - The app status.
  *  @returns {AppInfo | null} - Returns an object with app information or null if the app is not found.
  */
 export const getAppInfo = (id: string, status?: App['status']) => {

+ 1 - 1
src/server/services/system/system.service.ts

@@ -39,7 +39,7 @@ export class SystemServiceClass {
   /**
    * Get the current and latest version of Tipi
    *
-   * @returns {Promise<{ current: string; latest: string }>}
+   * @returns {Promise<{ current: string; latest: string }>} The current and latest version
    */
   public getVersion = async (): Promise<{ current: string; latest?: string }> => {
     try {

+ 3 - 1
src/server/trpc.ts

@@ -4,8 +4,10 @@ import { typeToFlattenedError, ZodError } from 'zod';
 import { type Context } from './context';
 
 /**
+ * Convert ZodError to a record
  *
- * @param errors
+ * @param {typeToFlattenedError<string>} errors - errors
+ * @returns {Record<string, string>} record
  */
 export function zodErrorsToRecord(errors: typeToFlattenedError<string>) {
   const record: Record<string, string> = {};