Skip to content
Open
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
4 changes: 2 additions & 2 deletions __tests__/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe.skip('AI agent integration', () => {
const [, agent] = await createTestStreamAndRealtimeClients();
let errorEvent: any = null;

agent.on('realtime.event', ({ event }) => {
agent.on('realtime.event', ({ event }: { event: any }) => {
if (event.type === 'error') {
errorEvent = event;
}
Expand Down Expand Up @@ -147,7 +147,7 @@ describe.skip('AI agent integration', () => {
required: ['lat', 'lng', 'location'],
},
},
async ({ lat, lng }) => {
async ({ lat, lng }: { lat: number; lng: number }) => {
const result = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&current=temperature_2m,wind_speed_10m`,
);
Expand Down
27 changes: 13 additions & 14 deletions __tests__/date-transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { randomUUID } from 'crypto';
import { createTestClient } from './create-test-client';
import { StreamClient } from '../src/StreamClient';
import { UserRequest } from '../src/gen/models';
import { nsToDate, nsToMs } from '../src/utils/time';

describe('Date conversion', () => {
describe('dates on responses', () => {
let client: StreamClient;
const user = {
id: 'stream-node-test-user',
Expand Down Expand Up @@ -36,18 +37,18 @@ describe('Date conversion', () => {

const createdAt = response.call.created_at;

expect(createdAt instanceof Date).toBe(true);
expect(now - createdAt.getTime()).toBeLessThan(oneMin);
expect(typeof createdAt).toBe('number');
expect(now - nsToMs(createdAt)).toBeLessThan(oneMin);

expect(response.call.starts_at instanceof Date).toBe(true);
expect(startsAt.getTime()).toEqual(response.call.starts_at?.getTime());
expect(typeof response.call.starts_at).toBe('number');
expect(startsAt.getTime()).toEqual(nsToMs(response.call.starts_at!));

expect(response.call.ended_at).toBeNull();

expect(response.members.length).toBeGreaterThan(0);

response.members.forEach((m) => {
expect(m.created_at instanceof Date).toBe(true);
expect(typeof m.created_at).toBe('number');
});

const queryResult = await client.video.queryCalls({
Expand Down Expand Up @@ -75,28 +76,26 @@ describe('Date conversion', () => {

const createdAt = response.channel!.created_at;

expect(createdAt instanceof Date).toBe(true);
expect(now - createdAt.getTime()).toBeLessThan(oneMin);
expect(typeof createdAt).toBe('number');
expect(now - nsToMs(createdAt)).toBeLessThan(oneMin);

expect(response.channel!.deleted_at).toBeUndefined();

expect(response.members.length).toBeGreaterThan(0);

response.members.forEach((m) => {
expect(m.created_at instanceof Date).toBe(true);
expect(typeof m.created_at).toBe('number');
});

const queryResult = await client.chat.queryChannels({
filter_conditions: {
created_at: { $lte: createdAt.toISOString() },
created_at: { $lte: nsToDate(createdAt).toISOString() },
},
limit: 10,
});

queryResult.channels.forEach((c) => {
expect(c.channel!.created_at.getTime()).toBeLessThanOrEqual(
createdAt.getTime(),
);
expect(c.channel!.created_at).toBeLessThanOrEqual(createdAt);
});

await channel.delete();
Expand All @@ -113,7 +112,7 @@ describe('Date conversion', () => {

const response = await client.upsertUsers([newUser]);

expect(response.users[newUser.id].created_at instanceof Date).toBe(true);
expect(typeof response.users[newUser.id].created_at).toBe('number');

expect(
typeof response.users[newUser.id].custom.created_at === 'string',
Expand Down
4 changes: 2 additions & 2 deletions __tests__/devices-push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from 'vitest';
import { randomUUID } from 'crypto';
import { createTestClient } from './create-test-client';
import { StreamClient } from '../src/StreamClient';
import { CreateDeviceRequest, PushProvider } from '../src/gen/models';
import { CreateDeviceRequest, PushProviderRequest } from '../src/gen/models';

describe('devices and push', () => {
let client: StreamClient;
Expand All @@ -16,7 +16,7 @@ describe('devices and push', () => {
push_provider_name: 'firebase',
user_id: user.id,
};
const pushProvider: PushProvider = {
const pushProvider: PushProviderRequest = {
name: 'test-push-provider',
type: 'xiaomi',
xiaomi_app_secret: '',
Expand Down
2 changes: 0 additions & 2 deletions __tests__/messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ describe('messages API', () => {
});

it('thread replies', async () => {
const now = new Date();
const response = await channel.sendMessage({
message: {
text: 'Hello from Stream Node SDK',
Expand All @@ -77,7 +76,6 @@ describe('messages API', () => {

const getResponse = await client.chat.getReplies({
parent_id: response.message.id,
created_at_after: now,
});

expect(
Expand Down
7 changes: 5 additions & 2 deletions __tests__/rate-limit.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { beforeAll, describe, expect, it } from 'vitest';
import { createTestClient } from './create-test-client';
import { StreamClient } from '../src/StreamClient';
import { StreamError } from '../src/types';

describe('rate limit', () => {
let client: StreamClient;
Expand Down Expand Up @@ -61,12 +62,14 @@ describe('rate limit', () => {
try {
await call.startTranscription();
throw new Error(`Method didn't throw`);
} catch (error) {
} catch (err) {
const error = err as StreamError;

expect(error.code).toBeDefined();
expect(error.metadata).toBeDefined();
expect(error.metadata.responseCode).toBe(404);

const rateLimit = error.metadata.rateLimit;
const rateLimit = error.metadata.rateLimit!;

expect(rateLimit.rateLimit).toBeDefined();
}
Expand Down
2 changes: 1 addition & 1 deletion generate-openapi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ CHAT_DIR="../chat"

rm -rf $OUTPUT_DIR

( cd $CHAT_DIR ; make openapi ; ./build/chat-manager openapi generate-client --language ts --spec ./releases/v2/serverside-api.yaml --output $OUTPUT_DIR )
( cd $CHAT_DIR ; make openapi ; ./build/chat-manager openapi generate-client --language ts --spec ./releases/v2/serverside-api.yaml --opt response_dates_as_number=true --output $OUTPUT_DIR )

yarn lint:gen
10 changes: 10 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ export {
InvalidWebhookError,
InvalidWebhookErrorMessages,
} from './src/utils/webhook';
export {
convertTimestampToDate,
dateToNs,
msToNs,
nowNs,
NS_PER_MS,
nsToDate,
nsToMs,
nsToRfc3339,
} from './src/utils/time';
1 change: 1 addition & 0 deletions src/gen/chat/ChannelApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class ChannelApi {

delete(request?: {
hard_delete?: boolean;
skip_truncate?: boolean;
}): Promise<StreamResponse<DeleteChannelResponse>> {
if (!this.id) {
throw new Error(
Expand Down
5 changes: 5 additions & 0 deletions src/gen/chat/ChatApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ export class ChatApi {
const body = {
operation: request?.operation,
filter: request?.filter,
hide_history_before: request?.hide_history_before,
synchronous: request?.synchronous,
custom_unset: request?.custom_unset,
members: request?.members,
custom_set: request?.custom_set,
Expand Down Expand Up @@ -419,6 +421,7 @@ export class ChatApi {
const body = {
cids: request?.cids,
hard_delete: request?.hard_delete,
skip_truncate: request?.skip_truncate,
};

const response = await this.apiClient.sendRequest<
Expand Down Expand Up @@ -551,9 +554,11 @@ export class ChatApi {
type: string;
id: string;
hard_delete?: boolean;
skip_truncate?: boolean;
}): Promise<StreamResponse<DeleteChannelResponse>> {
const queryParams = {
hard_delete: request?.hard_delete,
skip_truncate: request?.skip_truncate,
};
const pathParams = {
type: request?.type,
Expand Down
10 changes: 9 additions & 1 deletion src/gen/common/CommonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,11 @@ export class CommonApi {
async getPollOption(request: {
poll_id: string;
option_id: string;
user_id?: string;
}): Promise<StreamResponse<PollOptionResponse>> {
const queryParams = {
user_id: request?.user_id,
};
const pathParams = {
poll_id: request?.poll_id,
option_id: request?.option_id,
Expand All @@ -1269,7 +1273,7 @@ export class CommonApi {
'GET',
'/api/v2/polls/{poll_id}/options/{option_id}',
pathParams,
undefined,
queryParams,
);

decoders['PollOptionResponse']?.(response.body);
Expand Down Expand Up @@ -1440,6 +1444,8 @@ export class CommonApi {
ios?: boolean;
web?: boolean;
unity?: boolean;
unity_desktop?: boolean;
unity_console?: boolean;
endpoints?: string;
}): Promise<StreamResponse<GetRateLimitsResponse>> {
const queryParams = {
Expand All @@ -1448,6 +1454,8 @@ export class CommonApi {
ios: request?.ios,
web: request?.web,
unity: request?.unity,
unity_desktop: request?.unity_desktop,
unity_console: request?.unity_console,
endpoints: request?.endpoints,
};

Expand Down
63 changes: 63 additions & 0 deletions src/gen/feeds/FeedsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
DeleteFeedViewResponse,
DeleteFeedsBatchRequest,
DeleteFeedsBatchResponse,
DeleteUserInterestsResponse,
ExportFeedUserDataResponse,
FollowBatchRequest,
FollowBatchResponse,
Expand Down Expand Up @@ -174,6 +175,8 @@ import {
UpsertActivitiesResponse,
UpsertCollectionsRequest,
UpsertCollectionsResponse,
UpsertUserInterestsRequest,
UpsertUserInterestsResponse,
} from '../models';
import { decoders } from '../model-decoders/decoders';

Expand Down Expand Up @@ -726,13 +729,15 @@ export class FeedsApi {
id: string;
comment_sort?: string;
comment_limit?: number;
skip_own_followings?: boolean;
user_id?: string;
language?: string;
translate_text?: boolean;
}): Promise<StreamResponse<GetActivityResponse>> {
const queryParams = {
comment_sort: request?.comment_sort,
comment_limit: request?.comment_limit,
skip_own_followings: request?.skip_own_followings,
user_id: request?.user_id,
language: request?.language,
translate_text: request?.translate_text,
Expand Down Expand Up @@ -1720,6 +1725,7 @@ export class FeedsApi {
activity_processors: request?.activity_processors,
activity_selectors: request?.activity_selectors,
activity_filter: request?.activity_filter,
activity_marks: request?.activity_marks,
activity_processing: request?.activity_processing,
aggregation: request?.aggregation,
custom: request?.custom,
Expand Down Expand Up @@ -2282,6 +2288,7 @@ export class FeedsApi {
activity_processors: request?.activity_processors,
activity_selectors: request?.activity_selectors,
activity_filter: request?.activity_filter,
activity_marks: request?.activity_marks,
activity_processing: request?.activity_processing,
aggregation: request?.aggregation,
custom: request?.custom,
Expand Down Expand Up @@ -2319,6 +2326,7 @@ export class FeedsApi {
activity_processors: request?.activity_processors,
activity_selectors: request?.activity_selectors,
activity_filter: request?.activity_filter,
activity_marks: request?.activity_marks,
activity_processing: request?.activity_processing,
aggregation: request?.aggregation,
custom: request?.custom,
Expand Down Expand Up @@ -2633,6 +2641,8 @@ export class FeedsApi {
ios?: boolean;
web?: boolean;
unity?: boolean;
unity_desktop?: boolean;
unity_console?: boolean;
server_side?: boolean;
}): Promise<StreamResponse<GetFeedsRateLimitsResponse>> {
const queryParams = {
Expand All @@ -2641,6 +2651,8 @@ export class FeedsApi {
ios: request?.ios,
web: request?.web,
unity: request?.unity,
unity_desktop: request?.unity_desktop,
unity_console: request?.unity_console,
server_side: request?.server_side,
};

Expand Down Expand Up @@ -3184,6 +3196,31 @@ export class FeedsApi {
return { ...response.body, metadata: response.metadata };
}

async deleteUserInterests(request: {
user_id: string;
tags: Array<string>;
}): Promise<StreamResponse<DeleteUserInterestsResponse>> {
const queryParams = {
tags: request?.tags,
};
const pathParams = {
user_id: request?.user_id,
};

const response = await this.apiClient.sendRequest<
StreamResponse<DeleteUserInterestsResponse>
>(
'DELETE',
'/api/v2/feeds/users/{user_id}/interests',
pathParams,
queryParams,
);

decoders['DeleteUserInterestsResponse']?.(response.body);

return { ...response.body, metadata: response.metadata };
}

async getUserInterests(request: {
user_id: string;
limit?: number;
Expand All @@ -3208,4 +3245,30 @@ export class FeedsApi {

return { ...response.body, metadata: response.metadata };
}

async upsertUserInterests(
request: UpsertUserInterestsRequest & { user_id: string },
): Promise<StreamResponse<UpsertUserInterestsResponse>> {
const pathParams = {
user_id: request?.user_id,
};
const body = {
interests: request?.interests,
};

const response = await this.apiClient.sendRequest<
StreamResponse<UpsertUserInterestsResponse>
>(
'PUT',
'/api/v2/feeds/users/{user_id}/interests',
pathParams,
undefined,
body,
'application/json',
);

decoders['UpsertUserInterestsResponse']?.(response.body);

return { ...response.body, metadata: response.metadata };
}
}
Loading
Loading