Skip to content

Commit 09be7a4

Browse files
committed
fix: Moved to factory
1 parent 670fc69 commit 09be7a4

File tree

4 files changed

+83
-77
lines changed

4 files changed

+83
-77
lines changed

src/APIClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
FilePathOrFileObject,
1313
} from './types';
1414
import { AI21EnvConfig } from './EnvConfig';
15-
import { createFetchInstance, createFilesHandlerInstance } from './runtime';
15+
import { createFetchInstance, createFilesHandlerInstance } from './factory';
1616
import { Fetch } from 'fetch';
1717
import { BaseFilesHandler } from 'files/BaseFilesHandler';
1818
import { FormDataRequest } from 'types/API';

src/factory.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { BrowserFilesHandler } from './files/BrowserFilesHandler';
2+
import { BrowserFetch, Fetch, NodeFetch } from './fetch';
3+
import { NodeFilesHandler } from './files/NodeFilesHandler';
4+
import { BaseFilesHandler } from './files/BaseFilesHandler';
5+
import { isBrowser, isWebWorker } from 'runtime';
6+
7+
export function createFetchInstance(): Fetch {
8+
if (isBrowser || isWebWorker) {
9+
return new BrowserFetch();
10+
}
11+
12+
return new NodeFetch();
13+
}
14+
15+
export function createFilesHandlerInstance(): BaseFilesHandler {
16+
if (isBrowser || isWebWorker) {
17+
return new BrowserFilesHandler();
18+
}
19+
20+
return new NodeFilesHandler();
21+
}

src/files/NodeFilesHandler.ts

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,86 @@
11
import { FilePathOrFileObject } from 'types';
22
import { BaseFilesHandler } from './BaseFilesHandler';
33
import { FormDataRequest } from 'types/API';
4+
import { isNode } from 'runtime';
45

56
export class NodeFilesHandler extends BaseFilesHandler {
67
private async convertReadableStream(readableStream: ReadableStream): Promise<NodeJS.ReadableStream> {
7-
try {
8-
if (typeof window === 'undefined') {
9-
const { Readable } = await import('stream');
10-
const reader = readableStream.getReader();
8+
if (!isNode) {
9+
throw new Error('Stream conversion is not supported in browser environment');
10+
}
1111

12-
return new Readable({
13-
async read() {
14-
const { done, value } = await reader.read();
15-
if (done) {
16-
this.push(null);
17-
} else {
18-
this.push(value);
19-
}
20-
},
21-
});
22-
} else {
23-
throw new Error('Stream conversion is not supported in browser environment');
24-
}
25-
} catch (error) {
26-
console.error('Error in convertReadableStream:', error);
27-
throw error;
12+
const { Readable } = await import('stream');
13+
const reader = readableStream.getReader();
14+
15+
return new Readable({
16+
async read() {
17+
const { done, value } = await reader.read();
18+
done ? this.push(null) : this.push(value);
19+
},
20+
});
21+
}
22+
23+
private async handleStringFile(filePath: string, formData: any): Promise<void> {
24+
// eslint-disable-line @typescript-eslint/no-explicit-any
25+
if (!isNode) {
26+
throw new Error('File system operations are not supported in browser environment');
27+
}
28+
29+
const fs = await import('fs').then((m) => m.default || m);
30+
if (!fs.existsSync(filePath)) {
31+
throw new Error(`File not found: ${filePath}`);
2832
}
33+
34+
formData.append('file', fs.createReadStream(filePath), {
35+
filename: filePath.split('/').pop(),
36+
});
2937
}
3038

3139
async prepareFormDataRequest(file: FilePathOrFileObject): Promise<FormDataRequest> {
32-
console.log('Preparing form data request for Node.js');
3340
try {
34-
const FormData = await import('form-data').then(m => m.default || m);
35-
console.log('Successfully imported form-data module');
36-
41+
const FormData = await import('form-data').then((m) => m.default || m);
3742
const formData = new FormData();
38-
console.log('Created new FormData instance');
3943

4044
if (typeof file === 'string') {
41-
if (typeof window === 'undefined') {
42-
const fs = await import('fs').then(m => m.default || m);
43-
if (!fs.existsSync(file)) {
44-
throw new Error(`File not found: ${file}`);
45-
}
46-
console.log(`Appending file from path: ${file}`);
47-
formData.append('file', fs.createReadStream(file), { filename: file.split('/').pop() });
48-
} else {
49-
throw new Error('File system operations are not supported in browser environment');
50-
}
51-
} else if (file && typeof file === 'object') {
52-
console.log('Processing file object:', file);
53-
if ('buffer' in file) {
54-
console.log('Appending file from buffer');
55-
formData.append('file', file.buffer, { filename: file.name, contentType: file.type });
56-
} else if ('stream' in file && typeof file.stream === 'function') {
57-
console.log('Converting and appending file from stream');
58-
const nodeStream = await this.convertReadableStream(file.stream());
59-
formData.append('file', nodeStream, { filename: file.name, contentType: file.type });
60-
} else {
61-
throw new Error(`Invalid file object structure: ${JSON.stringify(file)}`);
62-
}
63-
} else {
45+
await this.handleStringFile(file, formData);
46+
return this.createFormDataResponse(formData);
47+
}
48+
49+
if (!file || typeof file !== 'object') {
6450
throw new Error(`Unsupported file type for Node.js file upload flow: ${file}`);
6551
}
6652

67-
const formDataHeaders = { 'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}` };
68-
console.log('FormData preparation completed successfully');
53+
if ('buffer' in file) {
54+
formData.append('file', file.buffer, {
55+
filename: file.name,
56+
contentType: file.type,
57+
});
58+
return this.createFormDataResponse(formData);
59+
}
60+
61+
if ('stream' in file && typeof file.stream === 'function') {
62+
const nodeStream = await this.convertReadableStream(file.stream());
63+
formData.append('file', nodeStream, {
64+
filename: file.name,
65+
contentType: file.type,
66+
});
67+
return this.createFormDataResponse(formData);
68+
}
6969

70-
return { formData, headers: formDataHeaders };
70+
throw new Error(`Unsupported file type for Node.js file upload flow: ${file}`);
7171
} catch (error) {
7272
console.error('Error in prepareFormDataRequest:', error);
73-
console.error('Error details:', error instanceof Error ? error.message : String(error));
7473
throw error;
7574
}
7675
}
76+
77+
private createFormDataResponse(formData: any): FormDataRequest {
78+
// eslint-disable-line @typescript-eslint/no-explicit-any
79+
return {
80+
formData,
81+
headers: {
82+
'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
83+
},
84+
};
85+
}
7786
}

src/runtime.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
import { BrowserFilesHandler } from './files/BrowserFilesHandler';
2-
import { BrowserFetch, Fetch, NodeFetch } from './fetch';
3-
import { NodeFilesHandler } from './files/NodeFilesHandler';
4-
import { BaseFilesHandler } from './files/BaseFilesHandler';
5-
61
export const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
72

83
/**
@@ -21,22 +16,3 @@ export const isWebWorker =
2116

2217
export const isNode =
2318
typeof process !== 'undefined' && Boolean(process.version) && Boolean(process.versions?.node);
24-
25-
export function createFetchInstance(): Fetch {
26-
if (isBrowser || isWebWorker) {
27-
console.log('Creating BrowserFetch instance');
28-
return new BrowserFetch();
29-
}
30-
31-
console.log('Creating NodeFetch instance');
32-
return new NodeFetch();
33-
}
34-
35-
export function createFilesHandlerInstance(): BaseFilesHandler {
36-
if (isBrowser || isWebWorker) {
37-
console.log('Creating BrowserFilesHandler instance');
38-
return new BrowserFilesHandler();
39-
}
40-
console.log('Creating NodeFilesHandler instance');
41-
return new NodeFilesHandler();
42-
}

0 commit comments

Comments
 (0)