Skip to content

Commit

Permalink
Fix noInvalidAny chat composites (#3987)
Browse files Browse the repository at this point in the history
  • Loading branch information
emlynmac authored Jan 9, 2024
1 parent 5c5af52 commit ee338e9
Show file tree
Hide file tree
Showing 13 changed files with 48 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
]
}
},
"postCreateCommand": "bash -i -c 'nvm install 16.19.0 && nvm use 16.19.0' && npm install @microsoft/rush -g && rush update"
"postCreateCommand": "bash -i -c 'nvm install 20.10.0 && nvm use 20.10.0' && npm install @microsoft/rush -g && rush update"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "patch",
"area": "fix",
"workstream": "TypeScript noImplicitAny fixes",
"comment": "Fix up noImplicitAny for Chat Composites",
"packageName": "@azure/communication-react",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "patch",
"area": "fix",
"workstream": "TypeScript noImplicitAny fixes",
"comment": "Fix up noImplicitAny for Chat Composites",
"packageName": "@azure/communication-react",
"email": "[email protected]",
"dependentChangeType": "patch"
}
2 changes: 1 addition & 1 deletion packages/chat-stateful-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export {

export type { StatefulChatClient, StatefulChatClientArgs, StatefulChatClientOptions } from './StatefulChatClient';
export type { ChatMessageWithStatus } from './types/ChatMessageWithStatus';
export { ChatError } from './ChatClientState';
export type {
ChatClientState,
ChatError,
ChatErrors,
ChatThreadClientState,
ChatThreadProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export type NotificationIconProps = {
export const NotificationIcon = (props: NotificationIconProps): JSX.Element => {
const { chatMessagesCount, label } = props;
const theme = useTheme();
const renderNumber = (numberOfMessages): JSX.Element => {
const renderNumber = (numberOfMessages: number): JSX.Element => {
if (numberOfMessages < 1) {
return <></>;
} else {
const textNumberOfMessages = numberOfMessages < 9 ? numberOfMessages : '9+';
return (
<Text role={'status'} aria-label={textNumberOfMessages + label} styles={notificationTextStyles(theme)}>
<Text role={'status'} aria-label={textNumberOfMessages + (label ?? '')} styles={notificationTextStyles(theme)}>
{textNumberOfMessages}
</Text>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ export const useUnreadMessagesTracker = (chatAdapter: ChatAdapter, isChatPaneVis
* Helper function to determine if the message in the event is a valid one from a user.
* Display name is used since system messages will not have one.
*/
const validNewChatMessage = (message): boolean =>
const validNewChatMessage = (message: ChatMessage): boolean =>
!!message.senderDisplayName && (message.type === 'text' || message.type === 'html');
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export type Mutable<T> = {

interface MockDeviceManager extends Mutable<DeviceManager> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
emit(event: any, data?: any);
emit(event: any, data?: any): any;
}

const createMockDeviceManager = (): MockDeviceManager => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { ChatMessage } from '@internal/react-components';
import React, { useCallback, useEffect, useMemo } from 'react';
import { useState } from 'react';
import { AvatarPersona, AvatarPersonaDataCallback } from '../common/AvatarPersona';
import { AvatarPersona, AvatarPersonaDataCallback, AvatarPersonaProps } from '../common/AvatarPersona';
import { useAdapter } from './adapter/ChatAdapterProvider';
import { ChatCompositeOptions } from './ChatComposite';
import { ChatHeader, getHeaderProps } from './ChatHeader';
Expand Down Expand Up @@ -151,7 +151,7 @@ export const ChatScreen = (props: ChatScreenProps): JSX.Element => {
const errorBarProps = usePropsFor(ErrorBar);

const onRenderAvatarCallback = useCallback(
(userId, defaultOptions) => {
(userId?: string, defaultOptions?: AvatarPersonaProps) => {
return (
<AvatarPersona
userId={userId}
Expand Down Expand Up @@ -196,7 +196,7 @@ export const ChatScreen = (props: ChatScreenProps): JSX.Element => {

/* @conditional-compile-remove(file-sharing) */
const onRenderFileDownloads = useCallback(
(userId, message: ChatMessage) => (
(userId: string, message: ChatMessage) => (
<_FileDownloadCards
userId={userId}
fileMetadata={message.files || []}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,17 +332,11 @@ export class AzureCommunicationChatAdapter implements ChatAdapter {
async downloadAttachments(options: { attachmentUrls: Record<string, string> }): Promise<AttachmentDownloadResult[]> {
return this.asyncTeeErrorToEventEmitter(async () => {
if (this.credential === undefined) {
const e = new Error();
e['target'] = 'ChatThreadClient.getMessage';
e['innerError'] = new Error('AccessToken is null');
throw e;
throw new ChatError('ChatThreadClient.getMessage', new Error('AccessToken is null'));
}
const accessToken = await this.credential.getToken();
if (!accessToken) {
const e = new Error();
e['target'] = 'ChatThreadClient.getMessage';
e['innerError'] = new Error('AccessToken is null');
throw e;
throw new ChatError('ChatThreadClient.getMessage', new Error('AccessToken is null'));
}

return this.downloadAuthenticatedFile(accessToken.token, options);
Expand All @@ -359,10 +353,7 @@ export class AzureCommunicationChatAdapter implements ChatAdapter {
try {
return await fetch(url, { headers });
} catch (err) {
const e = new Error();
e['target'] = 'ChatThreadClient.getMessage';
e['innerError'] = err;
throw e;
throw new ChatError('ChatThreadClient.getMessage', err as Error);
}
}

Expand Down Expand Up @@ -515,13 +506,13 @@ const convertEventToChatMessage = (
const isChatMessageEditedEvent = (
event: ChatMessageReceivedEvent | ChatMessageEditedEvent | ChatMessageDeletedEvent
): event is ChatMessageEditedEvent => {
return event['editedOn'] !== undefined;
return 'editedOn' in event;
};

const isChatMessageDeletedEvent = (
event: ChatMessageReceivedEvent | ChatMessageEditedEvent | ChatMessageDeletedEvent
): event is ChatMessageDeletedEvent => {
return event['deletedOn'] !== undefined;
return 'deletedOn' in event;
};

// only text/html message type will be received from event
Expand Down Expand Up @@ -734,5 +725,5 @@ export async function createAzureCommunicationChatAdapterFromClient(
}

const isChatError = (e: Error): e is ChatError => {
return e['target'] !== undefined && e['innerError'] !== undefined;
return 'target' in e && e['target'] !== undefined && 'innerError' in e && e['innerError'] !== undefined;
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ type PublicInterface<T> = { [K in keyof T]: T[K] };
* A public interface compatible stub for ChatClient.
*/
export class StubChatClient implements PublicInterface<ChatClient> {
private threadClient;
private threadClient: ChatThreadClient | undefined;

/**
* @param threadClient If set, an implementation of ChatThreadClient interface that is returned for *all* calls to
* {@getChatThreadClient()}.
*/
constructor(threadClient?: PublicInterface<ChatThreadClient>) {
this.threadClient = threadClient;
this.threadClient = threadClient as ChatThreadClient;
}

getChatThreadClient(): ChatThreadClient {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const BaseProvider = (
/**
* Before registering fluent icons, we should check DEFAULT_COMPOSITE_ICONS and strip out the key value pairs where value is undefined
*/
const iconsToRegister = {};
const iconsToRegister: { [key: string]: JSX.Element } = {};
Object.entries(DEFAULT_COMPOSITE_ICONS).forEach(([key, value]) => {
if (value) {
iconsToRegister[key] = value;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-composites/src/mocks/MockChatClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const createStatefulChatClientMock = (threadClient: PublicInterface<ChatT
* @returns
*/
export function createMockChatClient(threadClient: PublicInterface<ChatThreadClient>): ChatClient {
const mockEventHandlersRef = { value: {} };
const mockEventHandlersRef: { value: { [key: string]: ((e: Event) => void) | undefined | null } } = { value: {} };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const mockChatClient: ChatClient = {} as any;

Expand Down
19 changes: 11 additions & 8 deletions packages/react-composites/src/mocks/useFakeChatAdapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { ChatAdapter } from '../composites/ChatComposite/adapter/ChatAdapte
import { FakeChatClient, IChatClient, Model } from '@internal/fake-backends';

import { useEffect, useState } from 'react';
import { ChatClient, ChatParticipant, ChatThreadClient } from '@azure/communication-chat';
import { ChatClient, ChatParticipant, ChatThreadClient, CreateChatThreadResult } from '@azure/communication-chat';
import {
CommunicationTokenCredential,
CommunicationUserIdentifier,
Expand Down Expand Up @@ -89,7 +89,7 @@ export function _useFakeChatAdapters(args: _FakeChatAdapterArgs): _FakeChatAdapt
const initializeAdapters = async (
participants: ChatParticipant[],
chatClientModel: Model,
thread
thread: CreateChatThreadResult
): Promise<ChatAdapter[]> => {
const remoteAdapters: ChatAdapter[] = [];
for (const participant of participants) {
Expand Down Expand Up @@ -170,11 +170,14 @@ const registerChatThreadClientMethodErrors = (
chatThreadClientMethodErrors?: Partial<Record<keyof ChatThreadClient, _ChatThreadRestError>>
): void => {
for (const k in chatThreadClientMethodErrors) {
chatThreadClient[k] = () => {
throw new RestError(chatThreadClientMethodErrors[k].message ?? '', {
code: chatThreadClientMethodErrors[k].code,
statusCode: chatThreadClientMethodErrors[k].statusCode
});
};
if (k in chatThreadClient) {
const key = k as keyof Omit<ChatThreadClient, 'threadId'>;
chatThreadClient[key] = () => {
throw new RestError(chatThreadClientMethodErrors[key]?.message ?? '', {
code: chatThreadClientMethodErrors[key]?.code,
statusCode: chatThreadClientMethodErrors[key]?.statusCode
});
};
}
}
};

0 comments on commit ee338e9

Please sign in to comment.