Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions __tests__/file-uploads.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ describe.skip('channel file uploads', () => {
const fileBuffer = fs.readFileSync(filePath);

const response = await channel.uploadChannelFile({
// @ts-expect-error API spec says file should be a string
file: new File([fileBuffer], 'test-file.pdf'),
user: { id: user.id },
});
Expand Down Expand Up @@ -122,7 +121,6 @@ describe.skip('channel file uploads', () => {
];

const response = await channel.uploadChannelImage({
// @ts-expect-error API spec says file should be a string
file: new File([fileBuffer], 'test-image.jpg'),
user: { id: user.id },
upload_sizes: uploadSizes,
Expand Down
60 changes: 58 additions & 2 deletions __tests__/multipart.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ describe('multipart form data serialization', () => {
await chat.uploadChannelImage({
type: 'messaging',
id: 'channel-id',
// @ts-expect-error API spec says file should be a string
file: new File(['image-contents'], 'test-image.jpg'),
upload_sizes: [{ width: 100, height: 100 }],
user: { id: 'user-id' },
Expand All @@ -144,7 +143,6 @@ describe('multipart form data serialization', () => {
await chat.uploadChannelFile({
type: 'messaging',
id: 'channel-id',
// @ts-expect-error API spec says file should be a string
file: new File(['file-contents'], 'test-file.pdf'),
user: { id: 'user-id' },
});
Expand All @@ -153,4 +151,62 @@ describe('multipart form data serialization', () => {
expect(formData.get('user')).toBe('{"id":"user-id"}');
expect(formData.get('file')).toBeInstanceOf(File);
});

it('encodes a channel image upload made from a channel', async () => {
const fetchSpy = mockFetch();
const channel = new StreamChatClient(createApiClient()).channel(
'messaging',
'channel-id',
);

await channel.uploadChannelImage({
file: new File(['image-contents'], 'test-image.jpg'),
upload_sizes: [{ width: 100, height: 100 }],
user: { id: 'user-id' },
});

const [url, init] = fetchSpy.mock.calls[0];
expect(url).toContain('/api/v2/chat/channels/messaging/channel-id/image');
const formData = init!.body as FormData;
expect(formData.get('user')).toBe('{"id":"user-id"}');
expect(formData.get('upload_sizes')).toBe('[{"width":100,"height":100}]');
const sent = formData.get('file');
expect(sent).toBeInstanceOf(File);
expect((sent as File).name).toBe('test-image.jpg');
});

it('encodes a channel file upload made from a channel', async () => {
const fetchSpy = mockFetch();
const channel = new StreamChatClient(createApiClient()).channel(
'messaging',
'channel-id',
);

await channel.uploadChannelFile({
file: new File(['file-contents'], 'test-file.pdf'),
user: { id: 'user-id' },
});

const [url, init] = fetchSpy.mock.calls[0];
expect(url).toContain('/api/v2/chat/channels/messaging/channel-id/file');
const formData = init!.body as FormData;
expect(formData.get('user')).toBe('{"id":"user-id"}');
const sent = formData.get('file');
expect(sent).toBeInstanceOf(File);
expect((sent as File).name).toBe('test-file.pdf');
});

it('refuses a channel upload before the channel has an id', () => {
const fetchSpy = mockFetch();
const channel = new StreamChatClient(createApiClient()).channel(
'messaging',
);

expect(() =>
channel.uploadChannelFile({
file: new File(['file-contents'], 'test-file.pdf'),
}),
).toThrow("Channel isn't yet created");
expect(fetchSpy).not.toHaveBeenCalled();
});
});
24 changes: 23 additions & 1 deletion src/StreamChannel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ChannelApi } from './gen/chat/ChannelApi';
import { ChannelGetOrCreateRequest, QueryMembersPayload } from './gen/models';
import {
ChannelGetOrCreateRequest,
QueryMembersPayload,
UploadChannelFileRequest,
UploadChannelRequest,
} from './gen/models';
import { OmitTypeId } from './types';
import { File } from 'buffer';

export class StreamChannel extends ChannelApi {
get cid() {
Expand Down Expand Up @@ -36,4 +42,20 @@ export class StreamChannel extends ChannelApi {
},
});
}

// @ts-expect-error API spec says file should be a string
uploadChannelFile = (
request: Omit<UploadChannelFileRequest, 'file'> & { file: File },
) => {
// @ts-expect-error API spec says file should be a string
return super.uploadChannelFile(request);
};

// @ts-expect-error API spec says file should be a string
uploadChannelImage = (
request: Omit<UploadChannelRequest, 'file'> & { file: File },
) => {
// @ts-expect-error API spec says file should be a string
return super.uploadChannelImage(request);
};
}
30 changes: 29 additions & 1 deletion src/StreamChatClient.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
import { ChatApi } from './gen/chat/ChatApi';
import { UploadChannelFileRequest, UploadChannelRequest } from './gen/models';
import { StreamChannel } from './StreamChannel';
import { File } from 'buffer';

export class StreamChatClient extends ChatApi {
channel = (type: string, id?: string) => {
return new StreamChannel(this, type, id);
// The upload overrides below narrow `file` to File, so this class is no
// longer structurally a ChatApi, even though it is one at runtime
return new StreamChannel(this as unknown as ChatApi, type, id);
};

// @ts-expect-error API spec says file should be a string
uploadChannelFile = (
request: Omit<UploadChannelFileRequest, 'file'> & {
file: File;
type: string;
id: string;
},
) => {
// @ts-expect-error API spec says file should be a string
return super.uploadChannelFile(request);
};

// @ts-expect-error API spec says file should be a string
uploadChannelImage = (
request: Omit<UploadChannelRequest, 'file'> & {
file: File;
type: string;
id: string;
},
) => {
// @ts-expect-error API spec says file should be a string
return super.uploadChannelImage(request);
};
}
25 changes: 25 additions & 0 deletions src/gen/common/CommonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
BlockUsersResponse,
CancelImportV2TaskResponse,
CheckExternalStorageResponse,
CheckGCPPubSubRequest,
CheckGCPPubSubResponse,
CheckPushRequest,
CheckPushResponse,
CheckSNSRequest,
Expand Down Expand Up @@ -375,6 +377,29 @@ export class CommonApi {
return response;
}

async checkGCPPubSub(
request?: CheckGCPPubSubRequest,
): Promise<StreamResponse<CheckGCPPubSubResponse>> {
const body = {
gcp_pubsub_event_based_ordering_key_enabled:
request?.gcp_pubsub_event_based_ordering_key_enabled,
gcp_pubsub_region: request?.gcp_pubsub_region,
gcp_pubsub_topic: request?.gcp_pubsub_topic,
};

const response = await this.apiClient.sendRequest<CheckGCPPubSubResponse>(
'POST',
'/api/v2/check_gcp_pubsub',
undefined,
undefined,
body,
);

decoders['CheckGCPPubSubResponse']?.(response);

return response;
}

async checkPush(
request?: CheckPushRequest,
): Promise<StreamResponse<CheckPushResponse>> {
Expand Down
29 changes: 29 additions & 0 deletions src/gen/feeds/FeedsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
CastPollVoteRequest,
ChangeFeedVisibilityRequest,
ChangeFeedVisibilityResponse,
CommentFeedbackRequest,
CommentFeedbackResponse,
CreateCollectionsRequest,
CreateCollectionsResponse,
CreateFeedGroupRequest,
Expand Down Expand Up @@ -1433,6 +1435,31 @@ export class FeedsApi {
return response;
}

async commentFeedback(
request: CommentFeedbackRequest & { id: string },
): Promise<StreamResponse<CommentFeedbackResponse>> {
const pathParams = {
id: request?.id,
};
const body = {
hide: request?.hide,
user_id: request?.user_id,
user: request?.user,
};

const response = await this.apiClient.sendRequest<CommentFeedbackResponse>(
'POST',
'/api/v2/feeds/comments/{id}/feedback',
pathParams,
undefined,
body,
);

decoders['CommentFeedbackResponse']?.(response);

return response;
}

async updateCommentPartial(
request: UpdateCommentPartialRequest & { id: string },
): Promise<StreamResponse<UpdateCommentPartialResponse>> {
Expand Down Expand Up @@ -1746,6 +1773,7 @@ export class FeedsApi {
user_id: request?.user_id,
view: request?.view,
watch: request?.watch,
discard_actors: request?.discard_actors,
data: request?.data,
enrichment_options: request?.enrichment_options,
external_ranking: request?.external_ranking,
Expand Down Expand Up @@ -2934,6 +2962,7 @@ export class FeedsApi {
max_age_hours: request?.max_age_hours,
policy: request?.policy,
enabled: request?.enabled,
feed_groups: request?.feed_groups,
};

const response =
Expand Down
Loading
Loading