forked from cardosofelipe/fast-next-template
Refactor password reset flow and improve ESLint integration
- Extracted password reset logic into `PasswordResetConfirmContent` wrapped in `Suspense` for cleaner and more modular component structure. - Updated ESLint config to ignore generated files and added rules for stricter code quality (`eslint-comments`, `@typescript-eslint` adjustments). - Automated insertion of `eslint-disable` in auto-generated TypeScript files through `generate-api-client.sh`. - Replaced unsafe `any` type casts with safer `Record<string, unknown>` type assertions for TypeScript compliance. - Added `lint:tests` script for pre-commit test coverage checks. - Improved `useAuth` hooks and related type guards for better runtime safety and maintainability.
This commit is contained in:
@@ -67,7 +67,7 @@ function isAxiosError(error: unknown): error is AxiosError {
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'isAxiosError' in error &&
|
||||
(error as any).isAxiosError === true
|
||||
(error as Record<string, unknown>).isAxiosError === true
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,9 +92,9 @@ export function parseAPIError(error: unknown): APIError[] {
|
||||
error.response?.data &&
|
||||
typeof error.response.data === 'object' &&
|
||||
'errors' in error.response.data &&
|
||||
Array.isArray((error.response.data as any).errors)
|
||||
Array.isArray((error.response.data as Record<string, unknown>).errors)
|
||||
) {
|
||||
return (error.response.data as any).errors;
|
||||
return (error.response.data as { errors: APIError[] }).errors;
|
||||
}
|
||||
|
||||
// Network errors (no response)
|
||||
|
||||
5
frontend/src/lib/api/generated/.eslintrc.json
Normal file
5
frontend/src/lib/api/generated/.eslintrc.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": ["*"],
|
||||
"rules": {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type { AxiosError, AxiosInstance, RawAxiosRequestHeaders } from 'axios';
|
||||
import axios from 'axios';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type {
|
||||
AxiosError,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import { getAuthToken } from '../core/auth.gen';
|
||||
import type { QuerySerializerOptions } from '../core/bodySerializer.gen';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type {
|
||||
ArrayStyle,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type { Config } from './types.gen';
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
import { useAuthStore } from '@/stores/authStore';
|
||||
import type { User } from '@/stores/authStore';
|
||||
import { parseAPIError, getGeneralError } from '../errors';
|
||||
import { isTokenWithUser, type TokenWithUser } from '../types';
|
||||
import { isTokenWithUser } from '../types';
|
||||
import config from '@/config/app.config';
|
||||
|
||||
// ============================================================================
|
||||
@@ -359,8 +359,8 @@ export function usePasswordResetRequest(onSuccess?: (message: string) => void) {
|
||||
typeof data === 'object' &&
|
||||
data !== null &&
|
||||
'message' in data &&
|
||||
typeof (data as any).message === 'string'
|
||||
? (data as any).message
|
||||
typeof (data as Record<string, unknown>).message === 'string'
|
||||
? (data as { message: string }).message
|
||||
: 'Password reset email sent successfully';
|
||||
|
||||
if (onSuccess) {
|
||||
@@ -406,8 +406,8 @@ export function usePasswordResetConfirm(onSuccess?: (message: string) => void) {
|
||||
typeof data === 'object' &&
|
||||
data !== null &&
|
||||
'message' in data &&
|
||||
typeof (data as any).message === 'string'
|
||||
? (data as any).message
|
||||
typeof (data as Record<string, unknown>).message === 'string'
|
||||
? (data as { message: string }).message
|
||||
: 'Password reset successful';
|
||||
|
||||
if (onSuccess) {
|
||||
@@ -456,8 +456,8 @@ export function usePasswordChange(onSuccess?: (message: string) => void) {
|
||||
typeof data === 'object' &&
|
||||
data !== null &&
|
||||
'message' in data &&
|
||||
typeof (data as any).message === 'string'
|
||||
? (data as any).message
|
||||
typeof (data as Record<string, unknown>).message === 'string'
|
||||
? (data as { message: string }).message
|
||||
: 'Password changed successfully';
|
||||
|
||||
if (onSuccess) {
|
||||
|
||||
@@ -35,15 +35,16 @@ export interface SuccessResponse {
|
||||
* Type guard to check if response includes user data
|
||||
*/
|
||||
export function isTokenWithUser(token: unknown): token is TokenWithUser {
|
||||
const obj = token as Record<string, unknown>;
|
||||
return (
|
||||
typeof token === 'object' &&
|
||||
token !== null &&
|
||||
'access_token' in token &&
|
||||
'user' in token &&
|
||||
typeof (token as any).access_token === 'string' &&
|
||||
typeof (token as any).user === 'object' &&
|
||||
(token as any).user !== null &&
|
||||
!Array.isArray((token as any).user)
|
||||
typeof obj.access_token === 'string' &&
|
||||
typeof obj.user === 'object' &&
|
||||
obj.user !== null &&
|
||||
!Array.isArray(obj.user)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,12 +52,13 @@ export function isTokenWithUser(token: unknown): token is TokenWithUser {
|
||||
* Type guard to check if response is a success message
|
||||
*/
|
||||
export function isSuccessResponse(response: unknown): response is SuccessResponse {
|
||||
const obj = response as Record<string, unknown>;
|
||||
return (
|
||||
typeof response === 'object' &&
|
||||
response !== null &&
|
||||
'success' in response &&
|
||||
'message' in response &&
|
||||
(response as any).success === true &&
|
||||
typeof (response as any).message === 'string'
|
||||
obj.success === true &&
|
||||
typeof obj.message === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user