Skip to content

Commit c31e425

Browse files
authored
Fix any type usage in proprietary/ (Stirling-Tools#5949)
# Description of Changes Follow on from Stirling-Tools#5934, expanding `any` type usage ban to the `proprietary/` folder
1 parent a96b95e commit c31e425

34 files changed

Lines changed: 341 additions & 266 deletions

frontend/eslint.config.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ export default defineConfig(
8383
},
8484
// Folders that have been cleaned up and are now conformant - stricter rules enforced here
8585
{
86-
files: ['src/saas/**/*.{js,mjs,jsx,ts,tsx}'],
86+
files: [
87+
'src/proprietary/**/*.{js,mjs,jsx,ts,tsx}',
88+
'src/saas/**/*.{js,mjs,jsx,ts,tsx}',
89+
],
8790
languageOptions: {
8891
parserOptions: {
8992
project: true,

frontend/src/proprietary/auth/springAuthClient.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
22
import { springAuth } from '@app/auth/springAuthClient';
33
import { startOAuthNavigation } from '@app/extensions/oauthNavigation';
44
import apiClient from '@app/services/apiClient';
5-
import { AxiosError } from 'axios';
5+
import { AxiosError, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';
66

77
// Mock apiClient
88
vi.mock('@app/services/apiClient');
@@ -45,7 +45,7 @@ describe('SpringAuthClient', () => {
4545
vi.mocked(apiClient.get).mockResolvedValueOnce({
4646
status: 200,
4747
data: { user: mockUser },
48-
} as any);
48+
} as unknown as AxiosResponse);
4949

5050
const result = await springAuth.getSession();
5151

@@ -74,7 +74,7 @@ describe('SpringAuthClient', () => {
7474
statusText: 'Unauthorized',
7575
data: {},
7676
headers: {},
77-
config: {} as any,
77+
config: {} as InternalAxiosRequestConfig,
7878
}
7979
);
8080

@@ -102,7 +102,7 @@ describe('SpringAuthClient', () => {
102102
statusText: 'Forbidden',
103103
data: {},
104104
headers: {},
105-
config: {} as any,
105+
config: {} as InternalAxiosRequestConfig,
106106
}
107107
);
108108

@@ -141,7 +141,7 @@ describe('SpringAuthClient', () => {
141141
expires_in: 3600,
142142
},
143143
},
144-
} as any);
144+
} as unknown as AxiosResponse);
145145

146146
// Spy on window.dispatchEvent
147147
const dispatchEventSpy = vi.spyOn(window, 'dispatchEvent');
@@ -208,7 +208,7 @@ describe('SpringAuthClient', () => {
208208
vi.mocked(apiClient.post).mockResolvedValueOnce({
209209
status: 200,
210210
data: { user: mockUser },
211-
} as any);
211+
} as unknown as AxiosResponse);
212212

213213
const result = await springAuth.signUp(credentials);
214214

@@ -259,7 +259,7 @@ describe('SpringAuthClient', () => {
259259
vi.mocked(apiClient.post).mockResolvedValueOnce({
260260
status: 200,
261261
data: {},
262-
} as any);
262+
} as unknown as AxiosResponse);
263263

264264
const result = await springAuth.signOut();
265265

@@ -308,7 +308,7 @@ describe('SpringAuthClient', () => {
308308
expires_in: 3600,
309309
},
310310
},
311-
} as any);
311+
} as unknown as AxiosResponse);
312312

313313
const result = await springAuth.refreshSession();
314314

frontend/src/proprietary/auth/springAuthClient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export interface User {
8585
is_anonymous?: boolean;
8686
isFirstLogin?: boolean;
8787
authenticationType?: string;
88-
app_metadata?: Record<string, any>;
88+
app_metadata?: Record<string, unknown>;
8989
}
9090

9191
export interface Session {
@@ -447,7 +447,7 @@ class SpringAuthClient {
447447
*/
448448
async signInWithOAuth(params: {
449449
provider: OAuthProvider;
450-
options?: { redirectTo?: string; queryParams?: Record<string, any> };
450+
options?: { redirectTo?: string; queryParams?: Record<string, string> };
451451
}): Promise<{ error: AuthError | null }> {
452452
try {
453453
const redirectPath = normalizeRedirectPath(params.options?.redirectTo);

frontend/src/proprietary/components/shared/ChangeUserPasswordModal.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useEffect, useMemo, useState } from 'react';
2+
import { isAxiosError } from 'axios';
23
import { useTranslation } from 'react-i18next';
34
import {
45
ActionIcon,
@@ -125,8 +126,10 @@ export default function ChangeUserPasswordModal({ opened, onClose, user, onSucce
125126
alert({ alertType: 'success', title: t('workspace.people.changePassword.success', 'Password updated successfully') });
126127
onSuccess();
127128
handleClose();
128-
} catch (error: any) {
129-
const errorMessage = error.response?.data?.message || error.response?.data?.error || error.message || t('workspace.people.changePassword.error', 'Failed to update password');
129+
} catch (error: unknown) {
130+
const errorMessage = isAxiosError(error)
131+
? (error.response?.data?.message || error.response?.data?.error || error.message)
132+
: (error instanceof Error ? error.message : undefined) || t('workspace.people.changePassword.error', 'Failed to update password');
130133
alert({ alertType: 'error', title: errorMessage });
131134
} finally {
132135
setProcessing(false);

frontend/src/proprietary/components/shared/DividerWithText.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface TextDividerProps {
1212
export default function DividerWithText({ text, className = '', style, variant = 'default', respondsToDarkMode = true, opacity }: TextDividerProps) {
1313
const variantClass = variant === 'subcategory' ? 'subcategory' : '';
1414
const themeClass = respondsToDarkMode ? '' : 'force-light';
15-
const styleWithOpacity = opacity !== undefined ? { ...(style || {}), ['--text-divider-opacity' as any]: opacity } : style;
15+
const styleWithOpacity = opacity !== undefined ? { ...(style || {}), ['--text-divider-opacity' as string]: opacity } : style;
1616

1717
if (text) {
1818
return (

frontend/src/proprietary/components/shared/InviteMembersModal.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useEffect, useRef } from 'react';
2+
import { isAxiosError } from 'axios';
23
import { useTranslation } from 'react-i18next';
34
import {
45
Modal,
@@ -158,9 +159,11 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
158159
forceChange: false,
159160
forceMFA: false,
160161
});
161-
} catch (error: any) {
162+
} catch (error: unknown) {
162163
console.error('Failed to invite user:', error);
163-
const errorMessage = error.response?.data?.message || error.response?.data?.error || error.message || t('workspace.people.addMember.error');
164+
const errorMessage = isAxiosError(error)
165+
? (error.response?.data?.message || error.response?.data?.error || error.message)
166+
: (error instanceof Error ? error.message : undefined) || t('workspace.people.addMember.error');
164167
alert({ alertType: 'error', title: errorMessage });
165168
} finally {
166169
setProcessing(false);
@@ -211,12 +214,11 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
211214
body: response.errors || response.error
212215
});
213216
}
214-
} catch (error: any) {
217+
} catch (error: unknown) {
215218
console.error('Failed to invite users:', error);
216-
const errorMessage = error.response?.data?.message ||
217-
error.response?.data?.error ||
218-
error.message ||
219-
t('workspace.people.emailInvite.error', 'Failed to send invites');
219+
const errorMessage = isAxiosError(error)
220+
? (error.response?.data?.message || error.response?.data?.error || error.message)
221+
: (error instanceof Error ? error.message : undefined) || t('workspace.people.emailInvite.error', 'Failed to send invites');
220222
alert({ alertType: 'error', title: errorMessage });
221223
} finally {
222224
setProcessing(false);
@@ -239,9 +241,11 @@ export default function InviteMembersModal({ opened, onClose, onSuccess }: Invit
239241
if (inviteLinkForm.sendEmail && inviteLinkForm.email) {
240242
alert({ alertType: 'success', title: t('workspace.people.inviteLink.emailSent', 'Invite link generated and sent via email') });
241243
}
242-
} catch (error: any) {
244+
} catch (error: unknown) {
243245
console.error('Failed to generate invite link:', error);
244-
const errorMessage = error.response?.data?.message || error.response?.data?.error || error.message || t('workspace.people.inviteLink.error', 'Failed to generate invite link');
246+
const errorMessage = isAxiosError(error)
247+
? (error.response?.data?.message || error.response?.data?.error || error.message)
248+
: (error instanceof Error ? error.message : undefined) || t('workspace.people.inviteLink.error', 'Failed to generate invite link');
245249
alert({ alertType: 'error', title: errorMessage });
246250
} finally {
247251
setProcessing(false);

frontend/src/proprietary/components/shared/ManageBillingButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ export const ManageBillingButton: React.FC<ManageBillingButtonProps> = ({
3434
// Open billing portal in new tab
3535
window.open(response.url, '_blank');
3636
setLoading(false);
37-
} catch (error: any) {
37+
} catch (error: unknown) {
3838
console.error('Failed to open billing portal:', error);
3939
alert({
4040
alertType: 'error',
4141
title: t('billing.portal.error', 'Failed to open billing portal'),
42-
body: error.message || 'Please try again or contact support.',
42+
body: (error instanceof Error ? error.message : undefined) || 'Please try again or contact support.',
4343
});
4444
setLoading(false);
4545
}

frontend/src/proprietary/components/shared/UpgradeBanner.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const UpgradeBanner: React.FC = () => {
8686
const scenarioProvidesInfo =
8787
scenarioKey && scenarioKey !== 'unknown' && scenarioKey !== 'licensed';
8888
const derivedIsAdmin = scenarioProvidesInfo
89-
? scenarioKey!.includes('admin')
89+
? scenarioKey.includes('admin')
9090
: isAdmin;
9191
const derivedHasPaidLicense =
9292
scenarioKey === 'licensed'
@@ -95,10 +95,10 @@ const UpgradeBanner: React.FC = () => {
9595
? hasPaidLicense
9696
: false;
9797
const derivedIsUnderLimit = scenarioProvidesInfo
98-
? scenarioKey!.includes('under-limit')
98+
? scenarioKey.includes('under-limit')
9999
: isUnderLimit === true;
100100
const derivedIsOverLimit = scenarioProvidesInfo
101-
? scenarioKey!.includes('over-limit')
101+
? scenarioKey.includes('over-limit')
102102
: isOverLimit === true;
103103

104104
const effectiveIsAdmin = scenario

frontend/src/proprietary/components/shared/config/configSections/AdminAdvancedSection.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useCallback, useEffect, useMemo, useState } from 'react';
2+
import { isAxiosError } from 'axios';
23
import { useTranslation } from 'react-i18next';
34
import { NumberInput, Switch, Button, Stack, Paper, Text, Loader, Group, Accordion, TextInput, MultiSelect } from '@mantine/core';
45
import { alert } from '@app/components/toast';
@@ -72,7 +73,7 @@ export default function AdminAdvancedSection() {
7273
isFieldPending,
7374
} = useAdminSettings<AdvancedSettingsData>({
7475
sectionName: 'advanced',
75-
fetchTransformer: async (): Promise<AdvancedSettingsData & { _pending?: Record<string, any> }> => {
76+
fetchTransformer: async (): Promise<AdvancedSettingsData & { _pending?: Record<string, unknown> }> => {
7677
const [systemResponse, processExecutorResponse] = await Promise.all([
7778
apiClient.get('/api/v1/admin/settings/section/system'),
7879
apiClient.get('/api/v1/admin/settings/section/processExecutor')
@@ -81,7 +82,7 @@ export default function AdminAdvancedSection() {
8182
const systemData = systemResponse.data || {};
8283
const processExecutorData = processExecutorResponse.data || {};
8384

84-
const result: AdvancedSettingsData & { _pending?: Record<string, any> } = {
85+
const result: AdvancedSettingsData & { _pending?: Record<string, unknown> } = {
8586
enableAlphaFunctionality: systemData.enableAlphaFunctionality || false,
8687
maxDPI: systemData.maxDPI || 0,
8788
enableUrlToPDF: systemData.enableUrlToPDF || false,
@@ -101,7 +102,7 @@ export default function AdminAdvancedSection() {
101102
};
102103

103104
// Merge pending blocks from both endpoints
104-
const pendingBlock: Record<string, any> = {};
105+
const pendingBlock: Record<string, unknown> = {};
105106
if (systemData._pending?.enableAlphaFunctionality !== undefined) {
106107
pendingBlock.enableAlphaFunctionality = systemData._pending.enableAlphaFunctionality;
107108
}
@@ -131,7 +132,7 @@ export default function AdminAdvancedSection() {
131132
return result;
132133
},
133134
saveTransformer: (settings) => {
134-
const deltaSettings: Record<string, any> = {
135+
const deltaSettings: Record<string, unknown> = {
135136
'system.enableAlphaFunctionality': settings.enableAlphaFunctionality,
136137
'system.maxDPI': settings.maxDPI,
137138
'system.enableUrlToPDF': settings.enableUrlToPDF,
@@ -281,9 +282,8 @@ export default function AdminAdvancedSection() {
281282
setManualDownloadLinks([]);
282283
} catch (error) {
283284
console.error('[AdminAdvancedSection] Download tessdata languages failed', error);
284-
const response = (error as any)?.response;
285-
const status = response?.status;
286-
const serverMessage = response?.data?.message;
285+
const status = isAxiosError(error) ? error.response?.status : undefined;
286+
const serverMessage = isAxiosError(error) ? error.response?.data?.message : undefined;
287287

288288
if (status === 403) {
289289
console.warn('[AdminAdvancedSection] Tessdata directory not writable, falling back to manual download:', serverMessage);
@@ -309,12 +309,12 @@ export default function AdminAdvancedSection() {
309309
}
310310

311311
let message: string;
312-
if (!response) {
312+
if (!isAxiosError(error) || !error.response) {
313313
message = t(
314314
'admin.settings.advanced.tessdataDir.downloadErrorNetwork',
315315
'Download failed due to a network error. Please check your connection and try again.'
316316
);
317-
} else if (status >= 500) {
317+
} else if (status !== undefined && status >= 500) {
318318
message = t(
319319
'admin.settings.advanced.tessdataDir.downloadErrorServer',
320320
'The server encountered an error while downloading tessdata languages. Please try again later.'

frontend/src/proprietary/components/shared/config/configSections/AdminAuditSection.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { useState, useEffect } from 'react';
2+
import { isAxiosError } from 'axios';
23
import { Tabs, Loader, Alert, Stack, Text, Button, Accordion } from '@mantine/core';
34
import { useTranslation } from 'react-i18next';
45
import { useNavigate } from 'react-router-dom';
@@ -35,9 +36,9 @@ const AdminAuditSection: React.FC = () => {
3536
setError(null);
3637
const status = await auditService.getSystemStatus();
3738
setSystemStatus(status);
38-
} catch (err: any) {
39+
} catch (err: unknown) {
3940
// Check if this is a permission/license error (403/404)
40-
const status = err?.response?.status;
41+
const status = isAxiosError(err) ? err.response?.status : undefined;
4142
if (status === 403 || status === 404) {
4243
setError('enterprise-license-required');
4344
} else {

0 commit comments

Comments
 (0)