feat: integrate OpenAPI generated clients#1760
Conversation
1d2959a to
3a85fb8
Compare
77a2d78 to
6d7cbe8
Compare
|
Size Change: -5.04 kB (-1.23%) Total Size: 403 kB 📦 View Changed
|
637babe to
e7de829
Compare
| if ( | ||
| isFileReference(fileLike) && | ||
| fileLike.duration && | ||
| localAttachment.type === 'voiceRecording' |
There was a problem hiding this comment.
From my personal testing, duration and waveform_data appeared only on attachments of type voiceRecording the rest seem to not have been using these properties so I clarified it here to make TS happy.
f077f72 to
ffdd92c
Compare
| export interface QueryBannedUsersPayload { | ||
| /** | ||
| * Filter conditions to apply to the query | ||
| */ | ||
| filter_conditions: Filters<{ |
There was a problem hiding this comment.
Filters are now part of the generated files.
| /** | ||
| * Custom data for this object | ||
| */ | ||
| custom: CustomReactionData; |
There was a problem hiding this comment.
custom fields are populated with a different, JS-based script. I wasn's sure how to integrate this within the OAPI generator - I'm open to suggestions though.
| export { LogLevelEnum } from '@stream-io/logger'; | ||
| export type { ConfigureLoggersOptions, LogLevel, Sink } from '@stream-io/logger'; | ||
|
|
||
| export const chatLoggerSystem = scopedLogger.createLoggerSystem<ChatLoggerScope>(); |
There was a problem hiding this comment.
The project now uses our logging system, no more this.logger.
| export type PollState = Omit<PollResponse_old, 'own_votes' | 'id'> & { | ||
| lastActivityAt: Date; // todo: would be ideal to get this from the BE | ||
| maxVotedOptionIds: OptionId[]; | ||
| ownVotesByOptionId: Record<OptionId, PollVote>; | ||
| ownAnswer?: PollAnswer; // each user can have only one answer | ||
| ownVotesByOptionId: Record<OptionId, PollVoteResponseData>; | ||
| ownAnswer?: PollVoteResponseData; // each user can have only one answer |
There was a problem hiding this comment.
@MartinCupela - I've tried porting poll-related types to the generated ones, but there were some inconsitencies and that's why PollResponse_old has been kept. We should make sure to drop it before official v10 release though.
| export function normalizeQuerySort<T extends Record<string, AscDesc | undefined>>( | ||
| sort: T | T[], | ||
| ) { | ||
| const sortFields: Array<{ direction: AscDesc; field: keyof T }> = []; | ||
| const sortArr = Array.isArray(sort) ? sort : [sort]; | ||
| for (const item of sortArr) { | ||
| const entries = Object.entries(item) as [keyof T, AscDesc][]; | ||
| if (entries.length > 1) { | ||
| console.warn( | ||
| "client._buildSort() - multiple fields in a single sort object detected. Object's field order is not guaranteed", | ||
| ); | ||
| } | ||
| for (const [field, direction] of entries) { | ||
| sortFields.push({ field, direction }); | ||
| } | ||
| } | ||
| return sortFields; | ||
| } |
There was a problem hiding this comment.
Sort normalization has been dropped, we no longer accept the object version or even short array version:
{ pinned_at: -1, archived_at: 1 }
// or
[{ pinned_at: -1 }, { archived_at: 1 }]The new version should look like this:
[{ field: "pinned_at", direction: -1 }, { field: "archived_at", direction: 1 }]This version also allows to pass type property which allows casting of a value to the specified type before sorting.
|
|
||
| export type SearchMessageSort = SearchMessageSortBase | Array<SearchMessageSortBase>; | ||
| export type ChannelSort = SortParamRequest[]; |
There was a problem hiding this comment.
All of these are the same and are fixed types without key suggestion - we should revisit this and generate this in a similar manner we generate filters.
| @@ -228,48 +229,49 @@ export class ChannelState { | |||
| // If message is already formatted we can skip the tasks below | |||
| // This will be true for messages that are already present at the state -> this happens when we perform merging of message sets | |||
| // This will be also true for message previews used by some SDKs | |||
| const isMessageFormatted = messagesToAdd[i].created_at instanceof Date; | |||
| const isMessageFormatted = | |||
| typeof (messagesToAdd[i] as LocalMessage).status === 'string'; | |||
| let message: ReturnType<ChannelState['formatMessage']>; | |||
| if (isMessageFormatted) { | |||
| message = messagesToAdd[i] as ReturnType<ChannelState['formatMessage']>; | |||
| } else { | |||
| message = this.formatMessage(messagesToAdd[i]); | |||
| } | |||
|
|
|||
| if (message.user && this._channel?.cid) { | |||
| /** | |||
| * Store the reference to user for this channel, so that when we have to | |||
| * handle updates to user, we can use the reference map, to determine which | |||
| * channels need to be updated with updated user object. | |||
| */ | |||
| this._channel | |||
| .getClient() | |||
| .state.updateUserReference(message.user, this._channel.cid); | |||
| } | |||
| if (message.user && this._channel?.cid) { | |||
| /** | |||
| * Store the reference to user for this channel, so that when we have to | |||
| * handle updates to user, we can use the reference map, to determine which | |||
| * channels need to be updated with updated user object. | |||
| */ | |||
| this._channel | |||
| .getClient() | |||
| .state.updateUserReference(message.user, this._channel.cid); | |||
| } | |||
|
|
|||
| if ( | |||
| initializing && | |||
| message.id && | |||
| this.threads[message.id] && | |||
| !this._channel.getClient().preventThreadCleanup | |||
| ) { | |||
| // If we are initializing the state of channel (e.g., in case of connection recovery), | |||
| // then in that case we remove thread related to this message from threads object. | |||
| // This way we can ensure that we don't have any stale data in thread object | |||
| // and consumer can refetch the replies. | |||
| delete this.threads[message.id]; | |||
| } | |||
| if ( | |||
| initializing && | |||
| message.id && | |||
| this.threads[message.id] && | |||
| !this._channel.getClient().preventThreadCleanup | |||
| ) { | |||
| // If we are initializing the state of channel (e.g., in case of connection recovery), | |||
| // then in that case we remove thread related to this message from threads object. | |||
| // This way we can ensure that we don't have any stale data in thread object | |||
| // and consumer can refetch the replies. | |||
| delete this.threads[message.id]; | |||
| } | |||
|
|
|||
| const shouldSkipLastMessageAtUpdate = | |||
| this._channel.getConfig()?.skip_last_msg_update_for_system_msgs && | |||
| message.type === 'system'; | |||
| const shouldSkipLastMessageAtUpdate = | |||
| this._channel.getConfig()?.skip_last_msg_update_for_system_msgs && | |||
| message.type === 'system'; | |||
|
|
|||
| if ( | |||
| !shouldSkipLastMessageAtUpdate && | |||
| (!this.last_message_at || | |||
| message.created_at.getTime() > this.last_message_at.getTime()) | |||
| ) { | |||
| this.last_message_at = new Date(message.created_at.getTime()); | |||
| } | |||
| if ( | |||
| !shouldSkipLastMessageAtUpdate && | |||
| (!this.last_message_at || | |||
| message.created_at.getTime() > this.last_message_at.getTime()) | |||
| ) { | |||
| this.last_message_at = new Date(message.created_at.getTime()); | |||
| } | |||
There was a problem hiding this comment.
This is the biggest change I can think of - first, notice the bracked placement after message = this.formatMessage(messagesToAdd[i]); and second message has been considered a LocalMessage if it had created_at converted to a Date instance. Newly - message is considered local if it has been given status field which is not being delivered as part of the response. Some of the SDK code relies on this field to be present in the messages received through the WS events - I'm not sure how that worked previously, I'll mark it in the stream-chat-react for further discussion.
807044b to
073d00d
Compare
9b8598c to
6386793
Compare
e3be54c to
f970219
Compare
No description provided.