Skip to content

Commit 53d1a3a

Browse files
committed
Implement global file upload endpoints
1 parent 0670858 commit 53d1a3a

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

__tests__/file-uploads.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { beforeAll, describe, it, expect } from 'vitest';
2+
import { createTestClient } from './create-test-client';
3+
import { StreamClient } from '../src/StreamClient';
4+
import fs from 'fs';
5+
import path from 'path';
6+
import { File } from 'buffer';
7+
8+
// Don't want to upload files and image every time we run the tests
9+
describe.skip('global file uploads', () => {
10+
let client: StreamClient;
11+
const user = {
12+
id: 'stream-node-test-user',
13+
role: 'admin',
14+
};
15+
16+
beforeAll(async () => {
17+
client = createTestClient();
18+
await client.upsertUsers([user]);
19+
});
20+
21+
it('upload and delete file', async () => {
22+
// Read the test PDF file from assets
23+
const filePath = path.join(__dirname, 'assets', 'test-file.pdf');
24+
const fileBuffer = fs.readFileSync(filePath);
25+
26+
const response = await client.uploadFile({
27+
file: new File([fileBuffer], 'test-file.pdf'),
28+
user: { id: user.id },
29+
});
30+
31+
expect(response).toBeDefined();
32+
expect(response.file).toBeDefined();
33+
expect(response.duration).toBeDefined();
34+
35+
const deleteResponse = await client.deleteFile({
36+
url: response.file,
37+
});
38+
39+
expect(deleteResponse).toBeDefined();
40+
});
41+
42+
it('upload image', async () => {
43+
// Read the test PDF file from assets
44+
const filePath = path.join(__dirname, 'assets', 'test-image.jpg');
45+
const fileBuffer = fs.readFileSync(filePath);
46+
47+
const uploadSizes = [
48+
{
49+
width: 100,
50+
height: 100,
51+
resize: 'scale',
52+
crop: 'center',
53+
},
54+
];
55+
56+
// Upload the file
57+
const response = await client.uploadImage({
58+
file: new File([fileBuffer], 'test-image.jpg'),
59+
user: { id: user.id },
60+
upload_sizes: uploadSizes,
61+
});
62+
63+
expect(response.upload_sizes?.length).toBe(1);
64+
expect(response.upload_sizes?.[0]).toMatchObject(uploadSizes[0]);
65+
const deleteResponse = await client.deleteImage({
66+
url: response.file,
67+
});
68+
69+
expect(deleteResponse).toBeDefined();
70+
});
71+
});

src/StreamClient.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { QueryBannedUsersPayload, UserRequest } from './gen/models';
88
import { StreamModerationClient } from './StreamModerationClient';
99
import { ApiClient } from './ApiClient';
1010
import { StreamFeedsClient } from './StreamFeedsClient';
11+
import { File } from 'buffer';
1112

1213
export interface StreamClientOptions {
1314
timeout?: number;
@@ -91,6 +92,30 @@ export class StreamClient extends CommonApi {
9192
return this.chat.queryBannedUsers(request);
9293
};
9394

95+
// @ts-expect-error API spec says file should be a string
96+
uploadFile = (request: Omit<FileUploadRequest, 'file'> & { file: File }) => {
97+
return super.uploadFile({
98+
// @ts-expect-error API spec says file should be a string
99+
file: request.file,
100+
// @ts-expect-error form data will only work if this is a string
101+
user: JSON.stringify(request.user),
102+
});
103+
};
104+
105+
// @ts-expect-error API spec says file should be a string
106+
uploadImage = (
107+
request: Omit<ImageUploadRequest, 'file'> & { file: File },
108+
) => {
109+
return super.uploadImage({
110+
// @ts-expect-error API spec says file should be a string
111+
file: request.file,
112+
// @ts-expect-error form data will only work if this is a string
113+
user: JSON.stringify(request.user),
114+
// @ts-expect-error form data will only work if this is a string
115+
upload_sizes: JSON.stringify(request.upload_sizes),
116+
});
117+
};
118+
94119
/**
95120
*
96121
* @param payload

0 commit comments

Comments
 (0)