mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-26 14:19:24 +00:00
Redesign ToolOperationConfig typing
This commit is contained in:
parent
3c131bc332
commit
70e10a4f93
@ -20,13 +20,13 @@ vi.mock('../../../utils/toolErrorHandler', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Import the mocked function
|
// Import the mocked function
|
||||||
import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
import { SingleFileToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
||||||
|
|
||||||
|
|
||||||
describe('useAddPasswordOperation', () => {
|
describe('useAddPasswordOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<AddPasswordFullParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = () => mockUseToolOperation.mock.calls[0][0] as SingleFileToolOperationConfig<AddPasswordFullParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
@ -91,7 +91,7 @@ describe('useAddPasswordOperation', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const testFile = new File(['test content'], 'test.pdf', { type: 'application/pdf' });
|
const testFile = new File(['test content'], 'test.pdf', { type: 'application/pdf' });
|
||||||
const formData = buildFormData(testParameters, testFile as any /* FIX ME */);
|
const formData = buildFormData(testParameters, testFile);
|
||||||
|
|
||||||
// Verify the form data contains the file
|
// Verify the form data contains the file
|
||||||
expect(formData.get('fileInput')).toBe(testFile);
|
expect(formData.get('fileInput')).toBe(testFile);
|
||||||
@ -112,7 +112,7 @@ describe('useAddPasswordOperation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
{ property: 'multiFileEndpoint' as const, expectedValue: false },
|
{ property: 'toolType' as const, expectedValue: 'singleFile' },
|
||||||
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/add-password' },
|
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/add-password' },
|
||||||
{ property: 'filePrefix' as const, expectedValue: 'translated-addPassword.filenamePrefix_' },
|
{ property: 'filePrefix' as const, expectedValue: 'translated-addPassword.filenamePrefix_' },
|
||||||
{ property: 'operationType' as const, expectedValue: 'addPassword' }
|
{ property: 'operationType' as const, expectedValue: 'addPassword' }
|
||||||
|
@ -20,11 +20,11 @@ export const useAddPasswordOperation = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return useToolOperation<AddPasswordFullParameters>({
|
return useToolOperation<AddPasswordFullParameters>({
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'addPassword',
|
operationType: 'addPassword',
|
||||||
endpoint: '/api/v1/security/add-password',
|
endpoint: '/api/v1/security/add-password',
|
||||||
buildFormData,
|
|
||||||
filePrefix: t('addPassword.filenamePrefix', 'encrypted') + '_',
|
filePrefix: t('addPassword.filenamePrefix', 'encrypted') + '_',
|
||||||
multiFileEndpoint: false,
|
getErrorMessage: createStandardErrorHandler(t('addPassword.error.failed', 'An error occurred while encrypting the PDF.')),
|
||||||
getErrorMessage: createStandardErrorHandler(t('addPassword.error.failed', 'An error occurred while encrypting the PDF.'))
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,12 +20,12 @@ vi.mock('../../../utils/toolErrorHandler', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Import the mocked function
|
// Import the mocked function
|
||||||
import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
import { SingleFileToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
||||||
|
|
||||||
describe('useChangePermissionsOperation', () => {
|
describe('useChangePermissionsOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<ChangePermissionsParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = () => mockUseToolOperation.mock.calls[0][0] as SingleFileToolOperationConfig<ChangePermissionsParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
@ -86,7 +86,7 @@ describe('useChangePermissionsOperation', () => {
|
|||||||
const buildFormData = callArgs.buildFormData;
|
const buildFormData = callArgs.buildFormData;
|
||||||
|
|
||||||
const testFile = new File(['test content'], 'test.pdf', { type: 'application/pdf' });
|
const testFile = new File(['test content'], 'test.pdf', { type: 'application/pdf' });
|
||||||
const formData = buildFormData(testParameters, testFile as any /* FIX ME */);
|
const formData = buildFormData(testParameters, testFile);
|
||||||
|
|
||||||
// Verify the form data contains the file
|
// Verify the form data contains the file
|
||||||
expect(formData.get('fileInput')).toBe(testFile);
|
expect(formData.get('fileInput')).toBe(testFile);
|
||||||
@ -106,7 +106,7 @@ describe('useChangePermissionsOperation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
{ property: 'multiFileEndpoint' as const, expectedValue: false },
|
{ property: 'toolType' as const, expectedValue: 'singleFile' },
|
||||||
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/add-password' },
|
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/add-password' },
|
||||||
{ property: 'filePrefix' as const, expectedValue: 'permissions_' },
|
{ property: 'filePrefix' as const, expectedValue: 'permissions_' },
|
||||||
{ property: 'operationType' as const, expectedValue: 'changePermissions' }
|
{ property: 'operationType' as const, expectedValue: 'changePermissions' }
|
||||||
|
@ -25,13 +25,13 @@ export const useChangePermissionsOperation = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return useToolOperation({
|
return useToolOperation({
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'changePermissions',
|
operationType: 'changePermissions',
|
||||||
endpoint: '/api/v1/security/add-password', // Change Permissions is a fake endpoint for the Add Password tool
|
endpoint: '/api/v1/security/add-password', // Change Permissions is a fake endpoint for the Add Password tool
|
||||||
buildFormData,
|
|
||||||
filePrefix: 'permissions_',
|
filePrefix: 'permissions_',
|
||||||
multiFileEndpoint: false,
|
|
||||||
getErrorMessage: createStandardErrorHandler(
|
getErrorMessage: createStandardErrorHandler(
|
||||||
t('changePermissions.error.failed', 'An error occurred while changing PDF permissions.')
|
t('changePermissions.error.failed', 'An error occurred while changing PDF permissions.')
|
||||||
)
|
),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -33,11 +33,11 @@ export const useCompressOperation = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return useToolOperation<CompressParameters>({
|
return useToolOperation<CompressParameters>({
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'compress',
|
operationType: 'compress',
|
||||||
endpoint: '/api/v1/misc/compress-pdf',
|
endpoint: '/api/v1/misc/compress-pdf',
|
||||||
buildFormData,
|
|
||||||
filePrefix: 'compressed_',
|
filePrefix: 'compressed_',
|
||||||
multiFileEndpoint: false, // Individual API calls per file
|
|
||||||
getErrorMessage: createStandardErrorHandler(t('compress.error.failed', 'An error occurred while compressing the PDF.'))
|
getErrorMessage: createStandardErrorHandler(t('compress.error.failed', 'An error occurred while compressing the PDF.'))
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -129,11 +129,10 @@ export const useConvertOperation = () => {
|
|||||||
}, [t]);
|
}, [t]);
|
||||||
|
|
||||||
return useToolOperation<ConvertParameters>({
|
return useToolOperation<ConvertParameters>({
|
||||||
operationType: 'convert',
|
toolType: 'custom',
|
||||||
endpoint: '', // Not used with customProcessor but required
|
|
||||||
buildFormData, // Not used with customProcessor but required
|
|
||||||
filePrefix: 'converted_',
|
|
||||||
customProcessor: customConvertProcessor, // Convert handles its own routing
|
customProcessor: customConvertProcessor, // Convert handles its own routing
|
||||||
|
operationType: 'convert',
|
||||||
|
filePrefix: 'converted_',
|
||||||
getErrorMessage: (error) => {
|
getErrorMessage: (error) => {
|
||||||
if (error.response?.data && typeof error.response.data === 'string') {
|
if (error.response?.data && typeof error.response.data === 'string') {
|
||||||
return error.response.data;
|
return error.response.data;
|
||||||
@ -142,6 +141,6 @@ export const useConvertOperation = () => {
|
|||||||
return error.message;
|
return error.message;
|
||||||
}
|
}
|
||||||
return t("convert.errorConversion", "An error occurred while converting the file.");
|
return t("convert.errorConversion", "An error occurred while converting the file.");
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -96,11 +96,11 @@ export const useOCROperation = () => {
|
|||||||
}, [t, extractZipFiles]);
|
}, [t, extractZipFiles]);
|
||||||
|
|
||||||
const ocrConfig: ToolOperationConfig<OCRParameters> = {
|
const ocrConfig: ToolOperationConfig<OCRParameters> = {
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'ocr',
|
operationType: 'ocr',
|
||||||
endpoint: '/api/v1/misc/ocr-pdf',
|
endpoint: '/api/v1/misc/ocr-pdf',
|
||||||
buildFormData,
|
|
||||||
filePrefix: 'ocr_',
|
filePrefix: 'ocr_',
|
||||||
multiFileEndpoint: false, // Process files individually
|
|
||||||
responseHandler, // use shared flow
|
responseHandler, // use shared flow
|
||||||
getErrorMessage: (error) =>
|
getErrorMessage: (error) =>
|
||||||
error.message?.includes('OCR tools') && error.message?.includes('not installed')
|
error.message?.includes('OCR tools') && error.message?.includes('not installed')
|
||||||
|
@ -20,12 +20,12 @@ vi.mock('../../../utils/toolErrorHandler', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Import the mocked function
|
// Import the mocked function
|
||||||
import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
import { SingleFileToolOperationConfig, ToolOperationHook, useToolOperation } from '../shared/useToolOperation';
|
||||||
|
|
||||||
describe('useRemovePasswordOperation', () => {
|
describe('useRemovePasswordOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<RemovePasswordParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = () => mockUseToolOperation.mock.calls[0][0] as SingleFileToolOperationConfig<RemovePasswordParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
@ -91,7 +91,7 @@ describe('useRemovePasswordOperation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
{ property: 'multiFileEndpoint' as const, expectedValue: false },
|
{ property: 'toolType' as const, expectedValue: 'singleFile' },
|
||||||
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/remove-password' },
|
{ property: 'endpoint' as const, expectedValue: '/api/v1/security/remove-password' },
|
||||||
{ property: 'filePrefix' as const, expectedValue: 'translated-removePassword.filenamePrefix_' },
|
{ property: 'filePrefix' as const, expectedValue: 'translated-removePassword.filenamePrefix_' },
|
||||||
{ property: 'operationType' as const, expectedValue: 'removePassword' }
|
{ property: 'operationType' as const, expectedValue: 'removePassword' }
|
||||||
|
@ -14,11 +14,11 @@ export const useRemovePasswordOperation = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return useToolOperation<RemovePasswordParameters>({
|
return useToolOperation<RemovePasswordParameters>({
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'removePassword',
|
operationType: 'removePassword',
|
||||||
endpoint: '/api/v1/security/remove-password',
|
endpoint: '/api/v1/security/remove-password',
|
||||||
buildFormData,
|
|
||||||
filePrefix: t('removePassword.filenamePrefix', 'decrypted') + '_',
|
filePrefix: t('removePassword.filenamePrefix', 'decrypted') + '_',
|
||||||
multiFileEndpoint: false,
|
|
||||||
getErrorMessage: createStandardErrorHandler(t('removePassword.error.failed', 'An error occurred while removing the password from the PDF.'))
|
getErrorMessage: createStandardErrorHandler(t('removePassword.error.failed', 'An error occurred while removing the password from the PDF.'))
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -22,11 +22,11 @@ export const useSanitizeOperation = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return useToolOperation<SanitizeParameters>({
|
return useToolOperation<SanitizeParameters>({
|
||||||
|
toolType: 'singleFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'sanitize',
|
operationType: 'sanitize',
|
||||||
endpoint: '/api/v1/security/sanitize-pdf',
|
endpoint: '/api/v1/security/sanitize-pdf',
|
||||||
buildFormData,
|
|
||||||
filePrefix: t('sanitize.filenamePrefix', 'sanitized') + '_',
|
filePrefix: t('sanitize.filenamePrefix', 'sanitized') + '_',
|
||||||
multiFileEndpoint: false, // Individual API calls per file
|
|
||||||
getErrorMessage: createStandardErrorHandler(t('sanitize.error.failed', 'An error occurred while sanitising the PDF.'))
|
getErrorMessage: createStandardErrorHandler(t('sanitize.error.failed', 'An error occurred while sanitising the PDF.'))
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,8 @@ import { ResponseHandler } from '../../../utils/toolResponseProcessor';
|
|||||||
// Re-export for backwards compatibility
|
// Re-export for backwards compatibility
|
||||||
export type { ProcessingProgress, ResponseHandler };
|
export type { ProcessingProgress, ResponseHandler };
|
||||||
|
|
||||||
|
export type ToolConfigType = 'singleFile' | 'multiFile' | 'custom';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for tool operations defining processing behavior and API integration.
|
* Configuration for tool operations defining processing behavior and API integration.
|
||||||
*
|
*
|
||||||
@ -20,49 +22,63 @@ export type { ProcessingProgress, ResponseHandler };
|
|||||||
* 2. Multi-file tools: multiFileEndpoint: true, single API call with all files
|
* 2. Multi-file tools: multiFileEndpoint: true, single API call with all files
|
||||||
* 3. Complex tools: customProcessor handles all processing logic
|
* 3. Complex tools: customProcessor handles all processing logic
|
||||||
*/
|
*/
|
||||||
export interface ToolOperationConfig<TParams = void> {
|
interface BaseToolOperationConfig {
|
||||||
/** Operation identifier for tracking and logging */
|
/** Operation identifier for tracking and logging */
|
||||||
operationType: string;
|
operationType: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* API endpoint for the operation. Can be static string or function for dynamic routing.
|
|
||||||
* Not used when customProcessor is provided.
|
|
||||||
*/
|
|
||||||
endpoint: string | ((params: TParams) => string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds FormData for API request. Signature determines processing approach:
|
|
||||||
* - (params, file: File) => FormData: Single-file processing
|
|
||||||
* - (params, files: File[]) => FormData: Multi-file processing
|
|
||||||
* Not used when customProcessor is provided.
|
|
||||||
*/
|
|
||||||
buildFormData: ((params: TParams, file: File) => FormData) | ((params: TParams, files: File[]) => FormData); /* FIX ME */
|
|
||||||
|
|
||||||
/** Prefix added to processed filenames (e.g., 'compressed_', 'split_') */
|
/** Prefix added to processed filenames (e.g., 'compressed_', 'split_') */
|
||||||
filePrefix: string;
|
filePrefix: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether this tool uses backends that accept MultipartFile[] arrays.
|
|
||||||
* - true: Single API call with all files (backend uses MultipartFile[])
|
|
||||||
* - false/undefined: Individual API calls per file (backend uses single MultipartFile)
|
|
||||||
* Ignored when customProcessor is provided.
|
|
||||||
*/
|
|
||||||
multiFileEndpoint?: boolean;
|
|
||||||
|
|
||||||
/** How to handle API responses (e.g., ZIP extraction, single file response) */
|
/** How to handle API responses (e.g., ZIP extraction, single file response) */
|
||||||
responseHandler?: ResponseHandler;
|
responseHandler?: ResponseHandler;
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom processing logic that completely bypasses standard file processing.
|
|
||||||
* When provided, tool handles all API calls, response processing, and file creation.
|
|
||||||
* Use for tools with complex routing logic or non-standard processing requirements.
|
|
||||||
*/
|
|
||||||
customProcessor?: (params: TParams, files: File[]) => Promise<File[]>;
|
|
||||||
|
|
||||||
/** Extract user-friendly error messages from API errors */
|
/** Extract user-friendly error messages from API errors */
|
||||||
getErrorMessage?: (error: any) => string;
|
getErrorMessage?: (error: any) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SingleFileToolOperationConfig<TParams> extends BaseToolOperationConfig {
|
||||||
|
/** This tool processes one file at a time. */
|
||||||
|
toolType: 'singleFile';
|
||||||
|
|
||||||
|
/** Builds FormData for API request. */
|
||||||
|
buildFormData: ((params: TParams, file: File) => FormData);
|
||||||
|
|
||||||
|
/** API endpoint for the operation. Can be static string or function for dynamic routing. */
|
||||||
|
endpoint: string | ((params: TParams) => string);
|
||||||
|
|
||||||
|
customProcessor?: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MultiFileToolOperationConfig<TParams> extends BaseToolOperationConfig {
|
||||||
|
/** This tool processes multiple files at once. */
|
||||||
|
toolType: 'multiFile';
|
||||||
|
|
||||||
|
/** Builds FormData for API request. */
|
||||||
|
buildFormData: ((params: TParams, files: File[]) => FormData);
|
||||||
|
|
||||||
|
/** API endpoint for the operation. Can be static string or function for dynamic routing. */
|
||||||
|
endpoint: string | ((params: TParams) => string);
|
||||||
|
|
||||||
|
customProcessor?: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomToolOperationConfig<TParams> extends BaseToolOperationConfig {
|
||||||
|
/** This tool has custom behaviour. */
|
||||||
|
toolType: 'custom';
|
||||||
|
|
||||||
|
buildFormData?: undefined;
|
||||||
|
endpoint?: undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom processing logic that completely bypasses standard file processing.
|
||||||
|
* This tool handles all API calls, response processing, and file creation.
|
||||||
|
* Use for tools with complex routing logic or non-standard processing requirements.
|
||||||
|
*/
|
||||||
|
customProcessor: (params: TParams, files: File[]) => Promise<File[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ToolOperationConfig<TParams = void> = SingleFileToolOperationConfig<TParams> | MultiFileToolOperationConfig<TParams> | CustomToolOperationConfig<TParams>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complete tool operation interface with execution capability
|
* Complete tool operation interface with execution capability
|
||||||
*/
|
*/
|
||||||
@ -100,7 +116,7 @@ export { createStandardErrorHandler } from '../../../utils/toolErrorHandler';
|
|||||||
* @param config - Tool operation configuration
|
* @param config - Tool operation configuration
|
||||||
* @returns Hook interface with state and execution methods
|
* @returns Hook interface with state and execution methods
|
||||||
*/
|
*/
|
||||||
export const useToolOperation = <TParams = void>(
|
export const useToolOperation = <TParams>(
|
||||||
config: ToolOperationConfig<TParams>
|
config: ToolOperationConfig<TParams>
|
||||||
): ToolOperationHook<TParams> => {
|
): ToolOperationHook<TParams> => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -140,15 +156,28 @@ export const useToolOperation = <TParams = void>(
|
|||||||
try {
|
try {
|
||||||
let processedFiles: File[];
|
let processedFiles: File[];
|
||||||
|
|
||||||
if (config.customProcessor) {
|
switch (config.toolType) {
|
||||||
actions.setStatus('Processing files...');
|
case 'singleFile':
|
||||||
processedFiles = await config.customProcessor(params, validFiles);
|
// Individual file processing - separate API call per file
|
||||||
} else {
|
const apiCallsConfig: ApiCallsConfig<TParams> = {
|
||||||
// Use explicit multiFileEndpoint flag to determine processing approach
|
endpoint: config.endpoint,
|
||||||
if (config.multiFileEndpoint) {
|
buildFormData: config.buildFormData,
|
||||||
|
filePrefix: config.filePrefix,
|
||||||
|
responseHandler: config.responseHandler
|
||||||
|
};
|
||||||
|
processedFiles = await processFiles(
|
||||||
|
params,
|
||||||
|
validFiles,
|
||||||
|
apiCallsConfig,
|
||||||
|
actions.setProgress,
|
||||||
|
actions.setStatus
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'multiFile':
|
||||||
// Multi-file processing - single API call with all files
|
// Multi-file processing - single API call with all files
|
||||||
actions.setStatus('Processing files...');
|
actions.setStatus('Processing files...');
|
||||||
const formData = (config.buildFormData as (params: TParams, files: File[]) => FormData)(params, validFiles);
|
const formData = config.buildFormData(params, validFiles);
|
||||||
const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint;
|
const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint;
|
||||||
|
|
||||||
const response = await axios.post(endpoint, formData, { responseType: 'blob' });
|
const response = await axios.post(endpoint, formData, { responseType: 'blob' });
|
||||||
@ -166,22 +195,12 @@ export const useToolOperation = <TParams = void>(
|
|||||||
processedFiles = await extractAllZipFiles(response.data);
|
processedFiles = await extractAllZipFiles(response.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
// Individual file processing - separate API call per file
|
|
||||||
const apiCallsConfig: ApiCallsConfig<TParams> = {
|
case 'custom':
|
||||||
endpoint: config.endpoint,
|
actions.setStatus('Processing files...');
|
||||||
buildFormData: config.buildFormData as (params: TParams, file: File) => FormData,
|
processedFiles = await config.customProcessor(params, validFiles);
|
||||||
filePrefix: config.filePrefix,
|
break;
|
||||||
responseHandler: config.responseHandler
|
|
||||||
};
|
|
||||||
processedFiles = await processFiles(
|
|
||||||
params,
|
|
||||||
validFiles,
|
|
||||||
apiCallsConfig,
|
|
||||||
actions.setProgress,
|
|
||||||
actions.setStatus
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processedFiles.length > 0) {
|
if (processedFiles.length > 0) {
|
||||||
|
@ -59,11 +59,11 @@ export const useSplitOperation = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return useToolOperation<SplitParameters>({
|
return useToolOperation<SplitParameters>({
|
||||||
|
toolType: 'multiFile',
|
||||||
|
buildFormData,
|
||||||
operationType: 'split',
|
operationType: 'split',
|
||||||
endpoint: (params) => getEndpoint(params),
|
endpoint: (params) => getEndpoint(params),
|
||||||
buildFormData: buildFormData, // Multi-file signature: (params, selectedFiles) => FormData
|
|
||||||
filePrefix: 'split_',
|
filePrefix: 'split_',
|
||||||
multiFileEndpoint: true, // Single API call with all files
|
|
||||||
getErrorMessage: createStandardErrorHandler(t('split.error.failed', 'An error occurred while splitting the PDF.'))
|
getErrorMessage: createStandardErrorHandler(t('split.error.failed', 'An error occurred while splitting the PDF.'))
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user